This question already has answers here:
jQuery toggle children of div
(4 answers)
Closed 4 years ago.
I'm trying to make an accordion and I'm using the same classes for each row. Like this.
$(document).ready(function() {
$(".faq-article").click(function() {
$(".faq-details").toggle();
})
});
.faq-details {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq">
<div class="faq-article">
<div class="title-faq">Question 1</div>
<div class="faq-details">answer</div>
</div>
<div class="faq-article">
<div class="title-faq">Question 2</div>
<div class="faq-details">answer 2</div>
</div>
</div>
I can't remember how to prevent showing all the faq-details when clicking on the first question title.
You need to use this as context of your search for the .faq-details element.
$(document).ready(function() {
$(".faq-article").click(function() {
$(".faq-details", this).toggle();
})
});
.faq-details {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq">
<div class="faq-article">
<div class="title-faq">Question 1</div>
<div class="faq-details">answer</div>
</div>
<div class="faq-article">
<div class="title-faq">Question 2</div>
<div class="faq-details">answer 2</div>
</div>
</div>
As there are multiple elements with class faq-article, when implementing toggle() on that class all elements are affected. To get the currently clicked element you have to target the current context of the click event by specifying this.
Change
$(".faq-details").toggle();
To
$(this).find(".faq-details").toggle(); OR $(".faq-details", this).toggle();
$(document).ready(function() {
$(".faq-article").click(function() {
$(this).find(".faq-details").toggle();
})
});
.faq-details {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq">
<div class="faq-article">
<div class="title-faq">Question 1</div>
<div class="faq-details">answer</div>
</div>
<div class="faq-article">
<div class="title-faq">Question 2</div>
<div class="faq-details">answer 2</div>
</div>
</div>
Related
Well, I have n elements with the class "class_one"
and certain other elements with the class "class_two".
These elements are nested and in some cases there are other elements in that nest, what I need is to select the next element with a specific class.
let class_one = document.querySelectorAll('.class_one');
class_one.forEach(element => {
element.addEventListener('click',()=>{
console.log("From this element, the next one containing the class class_two");
})
});
<div class="class_one">
click 1
</div>
<div class="class_two">elemento 1</div>
<div class="class_one">
click 2
</div>
<div class="class_four"></div>
<div class="class_two">elemento 2</div>
<div class="class_one">
click 3
</div>
<div class="class_six"></div>
<div class="class_two">elemento 3</div>
<div class="class_one">
click 4
</div>
<div class="class_five">click 5</div>
<div class="class_two">elemento 4</div>
<div class="class_one">
click 6
</div>
<div class="class_two"></div>
Personally, I would like an answer without using Jquery, but all are welcome.
With the press of a button, I want to toggle the class .active on the next div.bottom. These are basically accordions, but with a different structure.
Using nextElementSibling I guess won't work here to select the target element. How would one select such an element, that's neither a child nor a sibling (in plain JS)?
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button></button></div>
</div>
</div>
<div class="bottom"></div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button></button></div>
</div>
</div>
<div class="bottom"></div>
</div>
I'd do it by using closest to go up to the container .wrapper element, then querySelector to find the bottom element:
function onClick(event) {
const wrapper = event.target.closest(".wrapper");
const bottom = wrapper && wrapper.querySelector(".bottom");
if (bottom) {
bottom.classList.toggle("active");
}
}
Live Example:
// I've added event delegation here
document.body.addEventListener("click", function onClick(event) {
const button = event.target.closest(".inner button");
const wrapper = button && button.closest(".wrapper");
const bottom = wrapper && wrapper.querySelector(".bottom");
if (bottom) {
bottom.classList.toggle("active");
}
});
.active {
color: blue;
border: 1px solid black;
}
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button A</button></div>
</div>
</div>
<div class="bottom">Bottom A</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button B</button></div>
</div>
</div>
<div class="bottom">Bottom B</div>
</div>
Or the same thing using optional chaining (relatively new):
function onClick(event) {
const wrapper = event.target.closest(".wrapper");
const bottom = wrapper?.querySelector(".bottom");
bottom?.classList.toggle("active");
}
Live Example:
// I've added event delegation here
document.body.addEventListener("click", function onClick(event) {
const button = event.target.closest(".inner button");
const wrapper = button?.closest(".wrapper");
const bottom = wrapper?.querySelector(".bottom");
bottom?.classList.toggle("active");
});
.active {
color: blue;
border: 1px solid black;
}
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button A</button></div>
</div>
</div>
<div class="bottom">Bottom A</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<div><button>Button B</button></div>
</div>
</div>
<div class="bottom">Bottom B</div>
</div>
By using closest() you can traverse the DOM upwards. With this it's easy to just get the relevant .bottom and toggle the active class on this element.
document.querySelectorAll('button').forEach(button => {
button.addEventListener('click', (e) => {
e.currentTarget.closest('.wrapper').querySelector('.bottom').classList.toggle('active');
});
});
.bottom {
display: none
}
.bottom.active {
display: block
}
<div class="wrapper">
<div class="top">
<div class="inner">
<button type="button">Toggle</button>
</div>
</div>
<div class="bottom">Hidden content</div>
</div>
<div class="wrapper">
<div class="top">
<div class="inner">
<button type="button">Toggle 2</button>
</div>
</div>
<div class="bottom">Hidden content 2</div>
</div>
I am trying to close an accordion on the next click after opening an accordion item. Given the current way that I have it set up (below), what would be the best approach to accomplishing this? My code is the following:
HTML:
<div class="faq-accordion">
<section id="1">
<h4>Accordion Title</h4>
<div>
<p>Accordion Content</p>
</div>
</section>
</div>
Javascript:
$(document).ready(function(){
$('.faq-accordion h4').click(function(){
if( $(this).next().is(':hidden') ) {
$('.faq-accordion h4').removeClass('faq-active').next().slideUp();
$(this).addClass('faq-active').next().slideDown();
}
return false;
});
});
You can do it this way:
(function($) {
var accordions = $('.accordion .content').hide();
$('.accordion .header > a').click(function() {
accordions.slideUp();
if($(this).parent().next().is(':visible')) {
$(this).parent().next().slideUp();
} else {
$(this).parent().next().slideDown();
}
return false;
});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="accordion">
<div class="header">Accordion title 1</div>
<div class="content">Content 1</div>
<div class="header">Accordion title 2</div>
<div class="content">Content 2</div>
<div class="header">Accordion title 3</div>
<div class="content">Content 3</div>
</div>
Let me know if you have any questions.
I hope it helps.
I have managed to toggle a div with different links. But when i'm trying to make more boxes which the same it doesn't work anymore.
Imagine I have like 10 entries - all separated divs 'entry'
<div class="entry" id="1">
where i want to separately hide and show content with multiple links.
My Question is, I'm trying to fix this since 5 hours, but which one div entry its working, with more than one it is not working.
I tried to use
$(".entry").each(function() {
Here is my code:
$(document).ready(function() {
$(".entry").each(function() {
var b4c = $('.lower_menu').html(); // content of box 4 so that we cn refer to it later
$(".menu1,.menu2,.menu3").click(function() {
var active_content = $(".lower_menu").data('content');
var cls = $(this).attr('class');
if (active_content == '') {
$(".lower_menu").html($("." + cls + '_CONTENT').html())
$(".lower_menu").data('content', cls);
} else {
if (active_content == cls) {
$('.lower_menu').html(b4c).data('content', '');
} else {
$(".lower_menu").html($("." + cls + '_CONTENT').html())
$(".lower_menu").data('content', cls);
}
}
});
});
});
.menu1 {height:40px; background-color:red;}
.menu2 {height:40px; background-color:green;}
.menu3 {height:40px; background-color:blue;}
.menu1_CONTENT {display:none; background-color:red;}
.menu2_CONTENT {display:none; background-color:green;}
.menu3_CONTENT {display:none; background-color:blue;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="entry">
<div class="menu1">
<span id="arrow_prod" class="glyphicon glyphicon-chevron-down arrow"></span> Heading 1
</div>
<div class="menu2">BOX 2</div>
<div class="menu3">BOX 3</div>
<!-- data-content is to check do we have content or which boxes's content do we hv now -->
<div class="lower_menu" data-content=""></div>
<div class="menu1_CONTENT">CONTENT FOR BOX 1</div>
<div class="menu2_CONTENT">CONTENT FOR BOX 2</div>
<div class="menu3_CONTENT">CONTENT FOR BOX 3</div>
</div>
<div class="entry">
<div class="menu1">BOX 1</div>
<div class="menu2">BOX 2</div>
<div class="menu3">BOX 3</div>
<!-- data-content is to check do we have content or which boxes's content do we hv now -->
<div class="lower_menu" data-content=""></div>
<div class="menu1_CONTENT">CONTENT FOR BOX 1</div>
<div class="menu2_CONTENT">CONTENT FOR BOX 2</div>
<div class="menu3_CONTENT">CONTENT FOR BOX 3</div>
</div>
... and a JSFiddle
it's a official bug of the jquery! We found one guys ! YEEEHAA
So I have this
<div class="btns">
<div class="btn1"></div>
<div class="btn2"></div>
<div class="btn3"></div>
<div class="btn4"></div>
</div>
<div class="prevs">
<div class="pre1"></div>
<div class="pre2"></div>
<div class="pre3"></div>
<div class="pre4"></div>
</div>
http://jsfiddle.net/uzpxjukv/
You have btn1, btn2, btn3 and btn4. I'm trying to make it so that when you press btn1, the div with the class pre1 should then get "display: block;" or something to make it visible. Then when btn2 is clicked, pre1 turns invisible again and pre2 turns visible.
Maybe something like this? If there will be more buttons, it should be more optimalized.
$('.btns').find('div').click(function(){
$('.prevs').find('div').eq($(this).index()).toggle();
});
$('.btns').find('div').click(function(){
$('.prevs').find('div').eq($(this).index()).toggle();
});
.prevs div:not(.pre1) {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btns">
<div class="btn1">Button 1</div>
<div class="btn2">Button 2</div>
<div class="btn3">Button 3</div>
<div class="btn4">Button 4</div>
</div>
<div class="prevs">
<div class="pre1">Previews 1</div>
<div class="pre2">Previews 2</div>
<div class="pre3">Previews 3</div>
<div class="pre4">Previews 4</div>
</div>
JSFIDDLE DEMO -> http://jsfiddle.net/uzpxjukv/5/
$('.btns div').click(function() {
var classNumber = this.className.slice(-1);
$('.prevs div').hide();
$('.pre' + classNumber).show();
});
On click of the button div, first hide all the pre divs and then show only the relevant div.
Try it
$('.btns > div').on('click', function() {
var numberOfDiv = $(this).attr('class').slice('-1'),
prevs = $('.prevs');
prevs.find('> div').hide();
prevs.find('.pre' + numberOfDiv).show();
});
This example is with your html code, if is possible to change it, you can get a better code.
See the fiddle
I have changed your HTML a little bit..Changed the class attribute of the prevs divsti ids.
HTML
<div class="btns">
<div class="btn1" id="1" onClick="reply_click(this.id)"></div>
<div class="btn2" id="2" onClick="reply_click(this.id)"></div>
<div class="btn3" id="3" onClick="reply_click(this.id)"></div>
<div class="btn4" id="4" onClick="reply_click(this.id)"></div>
</div>
<div class="prevs">
<div id="pre1"></div>
<div id="pre2"></div>
<div id="pre3"></div>
<div id="pre4"></div>
</div>
JS
function reply_click(id) {
document.getElementById("pre" + id).style.display = "block";
}
Provided that you know what naming system the divs use, you could use something along these lines. (To see properly working, view using developer tool)
$('.btns div').on('click', function() {
var currClass = $(this).attr('class').slice(-1); //get end of number of div clicked
$('.prevs div').css('display', 'none'); //reset all divs to being hidden
$('.pre' + currClass).css('display', 'inline-block'); //show desired div
});
.btns div {
background-color: gray;
}
.btns div, .prevs div {
width: 2em;
height: 2em;
display: inline-block;
padding-right: 0.2em;
}
.prevs div {
background-color: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btns">
<div class="btn1"></div>
<div class="btn2"></div>
<div class="btn3"></div>
<div class="btn4"></div>
</div>
<div class="prevs">
<div class="pre1"></div>
<div class="pre2"></div>
<div class="pre3"></div>
<div class="pre4"></div>
</div>