I need - button on click to hide each div, but here in my code only hide the first one then not working.
const closeInnermenu = document.querySelector('closeInnrmenu');
const innerC = document.querySelector('.inner-container')
closeInnermenu.addEventListener('click', () => {
innerC.style.display = 'none'
})
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu"></button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu"></button>
</div>
Get all the button using document.querySelectorAll('.closeInnrmenu') instead of document.querySelector since this will only give first matching element. Then iterate and add event listener to the button so that on click get the closest div and add style to it.
Also there is a type error here const closeInnermenu = document.querySelector('closeInnrmenu');. You need to pass dot as class selector
document.querySelectorAll('.closeInnrmenu').forEach((item) => {
item.addEventListener('click', function() {
this.closest('div').style.display = 'none'
})
})
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu">Close</button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu">Close</button>
</div>
Use:
let buttonClose = document.querySelectorAll('.closeInnrmenu')
for(let btns of buttonClose){
btns.addEventListener('click', function func(e) {
this.parentNode.style.display = 'none'
})
}
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu">Close</button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu">Close</button>
</div>
You can delegate
If you do not want to wrap in a div, use
document.addEventListener('click'
Here I wrapped
document.getElementById("container").addEventListener('click', (e) => {
const tgt = e.target;
if (tgt.classList.contains("closeInnrmenu")) {
tgt.previousElementSibling.style.display = 'none'
}
})
<div id="container">
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu"></button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu"></button>
</div>
</div>
Related
My document structure is:
<div id="mainWindow">
<div id="subele1"></div>
</div>
<div id="subWindow">
<div id="subele2"></div>
</div>
I want to create a button so that the children subele1 and subele2 are interchanged every time the button is clicked.
UPD
function handleButtonClicked() {
const mainElement = document.getElementById('subele1')
const subElement = document.getElementById('subele2')
const mainElementValue = mainElement.innerHTML
mainElement.innerHTML = subElement.innerHTML
subElement.innerHTML = mainElementValue
}
<div id="mainWindow">
<div id="subele1">main Window!</div>
</div>
<div id="subWindow">
<div id="subele2">sub Window?</div>
</div>
<button id='main' onclick={handleButtonClicked()}>switch</button>
I am trying to create a function in jquery. I have three boxes with three buttons. when I click a button then a box will display and other boxes will be hidden. same thing with the other button.
$("#one").click(function () {
$(".box1").show();
$(".box2").hide();
$(".box3").hide();
});
$("#two").click(function () {
$(".box2").show();
$(".box1").hide();
$(".box3").hide();
});
$("#three").click(function () {
$(".box3").show();
$(".box1").hide();
$(".box2").hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box1" style="display:none">box one</div>
<div class="box2" style="display:none">box Two</div>
<div class="box3" style="display:none">box Three</div>
<button id="one" type="button">One</button>
<button id="two" type="button">Two</button>
<button id="three" type="button">Three</button>
my question is that is there any way to achieve my goal without repeat the same code multiple times.
There is a much easer approach to this, You could use Attributes.
Have a look below.
$(".container button").click(function(){
var className = "."+ $(this).attr("target");
$(".container div").hide() // hide all divs
// now view the target one
$(className).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="box1" style="display:none">box one</div>
<div class="box2" style="display:none">box Two</div>
<div class="box3" style="display:none">box Three</div>
<button id="one" target="box1" type="button">One</button>
<button id="two" target="box2" type="button">Two</button>
<button id="three" target="box3" type="button">Three</button>
</div>
Here's a way that utilizes the ID of your buttons and the ID of your divs to make a dynamic function
$(".button").click(function(e) {
// set up the object to map stuff
let obj = {
'one': 'box1',
'two': 'box2',
'three': 'box3'
};
$(".box").hide();
$("." + obj[e.target.id]).show();
});
.box {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box1 box">box one</div>
<div class="box2 box">box Two</div>
<div class="box3 box">box Three</div>
<button id="one" class='button' type="button">One</button>
<button id="two" class='button' type="button">Two</button>
<button id="three" class='button' type="button">Three</button>
When any button is clicked, hide all the messages. Then just show the message who's index within its class matches the index of the button within its group.
$("button").click(function (event) {
// Hide all the messages
$(".box").each(function(index, box){
$(box).hide();
});
// Show just the message that applies
$($(".box")[$("button").index(event.target)]).show();
});
.hidden { display:none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box hidden">box One</div>
<div class="box hidden">box Two</div>
<div class="box hidden">box Three</div>
<button type="button">One</button>
<button type="button">Two</button>
<button type="button">Three</button>
You can simply use the jQuery :not() selector.
$("#one").click(function () {
$(".box1").show();
$("div:not(.box1)").hide();
});
$("#two").click(function () {
$(".box2").show();
$("div:not(.box2)").hide();
});
$("#three").click(function () {
$(".box3").show();
$("div:not(.box3)").hide();
});
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>
How can target class="a-2" inside id="b" by clicking on class="a-1" also inside id="b"?
<div id="a">
<div class="a-1"></div>
<div class="a-2"></div>
</div>
<div id="b">
<div class="b-1"></div>
<div class="b-2"></div>
</div>
<div id="c">
<div class="c-1"></div>
<div class="c-2"></div>
</div>
You can always go through the parent:
element.parentNode.querySelector('.a-2')
You can select all sibling nodes by selecting all children of the parent of the clicked node and then filter out the node that is clicked.
const el = document.querySelectorAll('div > div');
const siblings = function(el) {
const nodes = el.parentNode.children;
return [...nodes].filter(node => node !== el)
}
el.forEach(function(e) {
e.addEventListener('click', function() {
siblings(this).forEach(node => {
console.log(node.textContent)
})
})
})
<div id="a">
<div class="a-1">a</div>
<div class="b-2">b</div>
<div class="c-2">c</div>
</div>
<div id="b">
<div class="a-1">a</div>
<div class="b-2">b</div>
</div>
<div id="c">
<div class="a-1">a</div>
<div class="b-2">b</div>
</div>
I'm trying to create simple script which toggles buttons that can be placed anywhere on the page and work individualy no matter how the structure is.
$(document).ready(function() {
$('.togBtn').each(function(i) {
$(this).click(function() {
$('.togItem').hide();
} else {
$('.togItem').show();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<div class="togBtn" id="togBtn-1">
<button>But 1</button>
<div class="togItem" id="togItem-1">Item 1</div>
</div>
<button class="togBtn" id="togBtn-2">But 2</button>
<button class="togBtn" id="togBtn-3">But 3</button>
<div class="togItem" id="togBtn-2">Item 2</div>
<div class="togItem" id="togBtn-3">Item 3</div>
</section>
There's several issues in your code. Firstly a click handler function cannot have an else block. Secondly you try to hide/show all .togItem elements instead of the one related to the clicked button.
To approach this more logically, group the button and the content to be shown together. Then you can use DOM traversal to find the related item when the button is clicked. In the example below I made both of them children of a div and used next() to relate them. Try this:
jQuery(function($) {
$('.togBtn').click(function() {
$(this).next('.togItem').toggle();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<div class="togBtnContainer">
<button class="togBtn">But 1</button>
<div class="togItem">Item 1</div>
</div>
<div class="togBtnContainer">
<button class="togBtn">But 2</button>
<div class="togItem">Item 2</div>
</div>
<div class="togBtnContainer">
<button class="togBtn">But 3</button>
<div class="togItem">Item 3</div>
</div>
</section>
If the HTML is spread out and the related elements are not siblings then you can instead use data attributes to relate them, like this:
jQuery(function($) {
$('.togBtn').click(function() {
var targetSelector = $(this).data('target');
$(targetSelector).toggle();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<div class="togBtn" id="togBtn-1" data-target="#togItem-1">
<button>But 1</button>
<div class="togItem" id="togItem-1">Item 1</div>
</div>
<button class="togBtn" id="togBtn-2" data-target="#togItem-2">But 2</button>
<button class="togBtn" id="togBtn-3" data-target="#togItem-3">But 3</button>
<div class="togItem" id="togItem-2">Item 2</div>
<div class="togItem" id="togItem-3">Item 3</div>
</section>
Get the id of the button (or its parent element if the button itself doesn't have one) with the help of .closest() and the "attribute starts with" selector (^=):
var togBtnId = $(this).closest('[id^="togBtn-"]').attr("id");
Then just replace togBtn with togItem to get the id of the related item and use this as the selector for .toggle():
$("#" + togBtnId.replace("togBtn", "togItem")).toggle();
Example:
$(".togBtn").on("click", function() {
var togBtnId = $(this)
.closest('[id^="togBtn-"]') // .closest() because "But 1" has no id itself but its parent
.attr("id");
if (togBtnId) {
$("#" + togBtnId.replace("togBtn", "togItem")).toggle();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<div class="togBtn" id="togBtn-1">
<button>But 1</button>
<div class="togItem" id="togItem-1">Item 1</div>
</div>
<button class="togBtn" id="togBtn-2">But 2</button>
<button class="togBtn" id="togBtn-3">But 3</button>
<div class="togItem" id="togItem-2">Item 2</div>
<div class="togItem" id="togItem-3">Item 3</div>
</section>