Reputation: 53
I basically want to make it possible to show and hide multiple blocks of text, completely separate to one another. So that when one of the buttons is pressed, the corresponding quote directly below it becomes visible (display: block), but only that quote.
This is what I have so far, but I have now ran in to a wall:
JS:
<script>
let btn = document.querySelectorAll('btn');
let quote = document.querySelectorAll('quote');
btn.addEventListener("click", function(){
if (quote.style.display == "block") {
quote.style.display = "none";
} else {
quote.style.display = "block";
}
});
</script>
HTML:
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
Upvotes: 4
Views: 3206
Reputation: 5767
You have to declare an event listener for every button in a loop and declare the quote inside the listener. I also reversed the display
property values.
You also forgot a dot in the btn
variable:
let btn = document.querySelectorAll('.btn')
let btn = document.querySelectorAll('.btn');
for (i = 0; i < btn.length; i++) {
btn[i].addEventListener('click', function () {
let quote = this.nextElementSibling;
console.log('quote: ', quote);
if (quote.style.display == "none") {
quote.style.display = "block";
} else {
quote.style.display = "none";
}
});
}
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
Upvotes: 2
Reputation: 1342
Using jQuery i made this:
With $(this)
the button you clicked on, and .next()
giving the next element.
you can find the next element (i added a check to make sure the next element has the class quote before running) and apply your styling
$('.btn').on('click', function() {
if ($(this).next().hasClass('quote')) {
$(this).next().css('display', 'block');
}
});
p {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
<button class="btn">Click here to see the quote</button>
<p class="quote">blah blah blah</p>
Upvotes: 0
Reputation: 124
First of all, if you want to select class, it should be querSelectorAll('.btn')
and querSelectorAll('.quote')
(begin with a .
).
Secondly, with querSelectorAll
, your btn
and quote
variable will be lists of nodes (you should name it btns
and quotes
btw) so you won't be able to add event listener to it. What you should do is iterate throw your list and add event listener for each item:
let btns = [...document.querySelectorAll('.btn');
btns.map(btn => btn.addEventListener('click', (btn, idx) => handleBtnClick(btn, idx));
Then in handleBtnClick
, you should select the div with corresponding idx
and make it visible, while the others div invisible:
const handleBtnClick = (btn, idx) => {
let quotes = [...document.querySelectorAll('.quote')];
quotes.map( (quote, quotedIdx) => {
if (quoteIdx === idx) {
quote.style.display = 'block';
} else {
quote.style.display = 'none';
}
}
This code is no optimizied, please refacto as you please
Upvotes: 0