I have a script which hides an image and displays a text on the click of a button. However, I have similar buttons doing the same action in different divs. When I click the button the first button gets affected, no matter what button is pressed.
How do I manage to fix this?
Underneath is my JS. How do I make it so that the button only affects itself, and not just the first button?
function hideText() {
const btn = document.querySelector('#info');
const infoHide = document.querySelector('.info-hide');
infoHide.style.display = "block"
btn.style.display = 'none'
setTimeout(()=>{btn.style.display = 'block'; infoHide.style.display= "none"}, 2000)
}
<div>
<button id="info" onClick="hideText()"> A button </button>
<div style="display:none;">Copied!</div>
</div>
<div>
<button id="info" onClick="hideText()"> A button </button>
<div style="display:none;">Copied!</div>
</div>
CodePudding user response:
I changed your event listener to be aware of the element that triggered the event. Actually that's not strictly an event listener but just a function that gets called when the event occurs.
There are better ways to deal with it using .addEventListener
function hideText(target) {
const infoHide = target.parentElement.querySelector('.info-hide');
infoHide.style.display = "block"
target.style.display = 'none'
setTimeout(() => {
target.style.display = 'block';
infoHide.style.display = "none";
}, 2000)
}
button{
cursor: pointer;
margin-bottom: 1rem;
}
<div>
<button id="info1" onClick="hideText(this);">A button</button>
<div style="display:none;">Copied!</div>
</div>
<div>
<button id="info2" onClick="hideText(this);">A button</button>
<div style="display:none;">Copied!</div>
</div>
Anyway as another user pointed out in comments, the id attribute should be unique so I edited the answer to fulfill that condition.
And here I added the approach using a strategy not involving the event listener defined declaratively in the html:
document.addEventListener('DOMContentLoaded',()=>{
document.querySelectorAll('.smartbutton').forEach((btn)=>{
btn.addEventListener('click', (event)=>{ hideText(event.target); });
});
});
function hideText(target) {
const infoHide = target.parentElement.querySelector('.info-hide');
infoHide.style.display = "block"
target.style.display = 'none'
setTimeout(() => {
target.style.display = 'block';
infoHide.style.display = "none";
}, 2000)
}
.smartbutton{
cursor: pointer;
margin-bottom: 1rem;
}
.info-hide{
display: none;
}
<div>
<button id="info1" >A button</button>
<div >Copied!</div>
</div>
<div>
<button id="info2" >A button</button>
<div >Copied!</div>
</div>
CodePudding user response:
querySelector pulls the first element that matches your string. Thats why always first button and first info gets affected. You can provide button itself with this
keyword and provide an id which determines the div to appear.
function hideText(button, infoClassname) {
const info = document.querySelector(`.${infoClassname}`);
console.log(button)
info.style.display = "block"
button.style.display = 'none'
setTimeout(() => {
button.style.display = 'block';
info.style.display = "none"
}, 2000)
}
<div>
<button id="info" onClick="hideText(this, 'info-hide-1')"> A button </button>
<div style="display:none;">Copied!</div>
</div>
<div>
<button id="info" onClick="hideText(this, 'info-hide-2')"> A button </button>
<div style="display:none;">Copied!</div>
</div>
CodePudding user response:
change your id in div from all 'info' to 'info1'/'info2'/'info3'/, and do same change in your js const btn = document.querySelector('#info1');