For any element that is clicked in the stack, the target element should be assigned a higher z-index than all of those that come before it in the DOM. Then it should translateY()
pixels up to the first element.
The desired result is for the target element to sit on top of the first element in the parent. Yet there is a bug where it makes it appear that some elements get a lower z-index . If this could be refactored better as well how could it be improved?
const divs = document.querySelectorAll("div");
divs.forEach((div) => {
div.addEventListener("click", (event) => {
let i = 0;
let previous_sibling = event.target.previousElementSibling;
while (previous_sibling != null) {
i ;
previous_sibling = previous_sibling.previousElementSibling;
}
event.target.style.cssText = `
position: relative;
z-index: ${i 1};
transform: translateY(-${i * 45}px);
`;
})
})
.box {
width: 300px;
height: 45px;
/* border: 1px solid; */
margin: auto;
}
section {
margin-top: 50px;
}
div {
transition: transform .75s linear;
}
#box1 {
background: red;
}
#box2 {
background: blue;
}
#box3 {
background: green;
}
#box4 {
background: orange;
}
#box5 {
background: purple;
}
#box6 {
background: teal;
}
<section>
<div class="box" id="box1">1</div>
<div class="box" id="box2">2</div>
<div class="box" id="box3">3</div>
<div class="box" id="box4">4</div>
<div class="box" id="box5">5</div>
<div class="box" id="box6">6</div>
<div class="box" id="box1">7</div>
<div class="box" id="box2">8</div>
<div class="box" id="box3">9</div>
<div class="box" id="box4">10</div>
<div class="box" id="box5">11</div>
<div class="box" id="box6">12</div>
</section>
CodePudding user response:
Currently the z-index
gets calculated by the elements DOM position due to the use of previousElementSibling
and the simple counter. Since translateY
does not change the position of the elements in the DOM they can never be out of order. For example numer #3 can never be on top of #4 because it never is in the DOM. To change this behaviour you could simply store the highest z-index
(here in the dataset
of the section
) and reuse / add to it.
const divs = document.querySelectorAll("div");
divs.forEach((div) => {
div.addEventListener("click", (event) => {
//REM: Get the highest z-index
let tCurrentZ = ~~div.parentNode.dataset.zindex;
let i = 0;
let previous_sibling = event.target.previousElementSibling;
while (previous_sibling != null) {
i ;
previous_sibling = previous_sibling.previousElementSibling;
}
event.target.style.cssText = `
position: relative;
z-index: ${tCurrentZ};
transform: translateY(-${i * 45}px);
`;
//REM: Increase the highest z-index
div.parentNode.dataset.zindex = tCurrentZ 1
})
})
.box {
width: 300px;
height: 45px;
/* border: 1px solid; */
margin: auto;
}
section {
margin-top: 50px;
}
div {
transition: transform .75s linear;
}
#box1 {
background: red;
}
#box2 {
background: blue;
}
#box3 {
background: green;
}
#box4 {
background: orange;
}
#box5 {
background: purple;
}
#box6 {
background: teal;
}
<section>
<div class="box" id="box1">1</div>
<div class="box" id="box2">2</div>
<div class="box" id="box3">3</div>
<div class="box" id="box4">4</div>
<div class="box" id="box5">5</div>
<div class="box" id="box6">6</div>
<div class="box" id="box1">7</div>
<div class="box" id="box2">8</div>
<div class="box" id="box3">9</div>
<div class="box" id="box4">10</div>
<div class="box" id="box5">11</div>
<div class="box" id="box6">12</div>
</section>