The following code contains 2 buttons and their respective drop-down contents. When I click the first button, the other moves by itself. How do I stop this from happening?
var coll = document.getElementsByClassName("button");
var i;
for (i = 0; i < coll.length; i ) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block")
content.style.display = "none";
else
content.style.display = "block";
});
}
.content {
display: none;
}
<button type="button" style="position: static; left: 100;">For Copper Rollers</button>
<div style=" width: 48%; background-color: lightblue; padding: 10px; border-radius: 10px; margin-right: 5px; ">
</div>
<button type="button" style="position: static; left: 175px; ">For Rubber Rollers</button>
<div style="margin-left:50%; float: left; width: 48%; background-color: lightblue; padding: 10px; border-radius: 10px;">
</div>
CodePudding user response:
I would go with making the dropdown content have a position: asolute
(css), that way it won't affect any other elements on the page.
PS: make sure to keep accessibility in mind when making dropdowns, your current snippet unfortunately isn't.
CodePudding user response:
If you assign position:absolute
you can do some rudimentary calculations in Javascript to determine the position the content
should appear at. Is this more or less the desired effect?
document.querySelectorAll('button').forEach(( bttn, index )=>bttn.addEventListener('click',function(e){
this.classList.toggle("active");
// get the bounding box for the button so we can
// get a suitable height offset for content
let bb=this.getBoundingClientRect();
// find the content and toggle display state
let div=this.nextElementSibling;
div.style.display=div.style.display=='block' ? 'none' : 'block';
// find the current style properties for the content
let style=getComputedStyle( div );
let bbd=div.getBoundingClientRect();
// calculate x / y positions for content
let x=( Math.ceil( bbd.width ) parseInt( style.paddingLeft ) - parseInt( style.marginLeft ) ) * index;
let y=Math.ceil( bb.height ) Math.ceil( bb.bottom );
// apply those positions to the content
div.style.top=`${y}px`;
div.style.left=`${x}px`;
// identify content by parent
div.textContent=this.textContent.replace('For ','');
}));
body{
width:100%;
height:100vh;
}
button.button{
padding:0.25rem;
}
/*
assign the absolute position
to the content divs but let
javascript calculate x/y positions.
*/
.content {
position:absolute;
display: none;
width: calc( 50% - 3rem );
background-color:lightblue;
padding:1rem;
border-radius:10px;
border:1px solid grey;
float:none;
clear:none;
margin:0 0.25rem;
}
.content:first-of-type{
background:pink;
}
.active{
color:green
}
<!--
let css do the styling and positioning as `inline` styles
make updating a pain in the proverbial
-->
<button type="button" >For Copper Rollers</button>
<div ></div>
<button type="button">For Rubber Rollers</button>
<div ></div>