По клику на div сделать его поверх остальных
Есть несколько дивов с абсолютным позиционированием и накладываающиеся друг на друга. Я пытаюсь сделать так, чтобы при нажатии на div он становился поверх остальных.
let divs = document.querySelectorAll("div");
for (const div of divs) {
div.addEventListener("click", function () {
console.log(div.style.position);
if (div.style.position === "absolute")
div.style.position = "relative";
else div.style.position = "absolute";
});
}
<div style="background-color: 'red'; position: absolute">vfvf</div>
<div style="position: absolute">dasdasdasdasdasd</div>
Я пытался и через z-index, и так как в коде выше, но, видимо, я невнимательно читаю документацию, ибо ничего не получатся
Ответы (5 шт):
по-моему надо использовать z-index
, чтоб div
был поверх остальных div
-ов
let divs = document.querySelectorAll("div");
let maxZIndex = 1; //максимальный z-index
for (const div of divs) {
div.addEventListener("click", function() {
maxZIndex++; //увеличиваем индекс
div.style.zIndex = maxZIndex;
});
}
div {
width: 100px;
height: 100px;
position: absolute;
}
.red {
background-color: red;
top: 50px;
left: 50px;
}
.blue {
background-color: blue;
top: 100px;
left: 100px;
}
.green {
background-color: green;
top: 150px;
left: 150px;
}
<div class="red">Red</div>
<div class="blue">Blue</div>
<div class="green">Green</div>
Для того, чтобы элемент оказался поверх других можно обойтись и без индексного позиционирования, если манипулировать DOM.
С учётом того, что изначально все div
свалены в body
... достаточно и такого кода.
document.addEventListener('click', (e) => {
if(e.target.localName === 'div') document.body.append(e.target);
});
div {
width: 100px;
height: 100px;
position: absolute;
}
.red {
background-color: red;
top: 50px;
left: 50px;
}
.blue {
background-color: blue;
top: 100px;
left: 100px;
}
.green {
background-color: green;
top: 150px;
left: 150px;
}
.gold {
background-color: gold;
top: 200px;
left: 200px;
}
<div class="red">Red</div>
<div class="gold">Gold</div>
<div class="green">Green</div>
<div class="blue">Blue</div>
В случае с близкими к реальности условиями, когда есть обёртка, то одной строкой больше:
const wrapper = document.querySelector('.wrapper')
wrapper.addEventListener('click', (e) => {
wrapper.append(e.target)
});
div {
width: 100px;
height: 100px;
position: absolute;
}
.red {
background-color: red;
top: 50px;
left: 50px;
}
.blue {
background-color: blue;
top: 100px;
left: 100px;
}
.green {
background-color: green;
top: 150px;
left: 150px;
}
.gold {
background-color: gold;
top: 200px;
left: 200px;
}
<div class="wrapper">
<div class="red">Red</div>
<div class="gold">Gold</div>
<div class="green">Green</div>
<div class="blue">Blue</div>
</div>
Использование DOM-иерархии (перемещение элемента в конец контейнера) - один из простых способов поднять элемент поверх остальных — это переместить его в конец контейнера (родительского элемента). Визуально он окажется выше других элементов, так как в HTML порядок рендера элементов сверху вниз.
let divs = document.querySelectorAll("#container div");
for (const div of divs) {
div.addEventListener("click", function() {
div.parentNode.appendChild(div); // Перемещаем элемент в конец контейнера
});
}
div {
width: 100px;
height: 100px;
position: absolute;
}
.red {
background-color: rgb(167, 8, 8);
top: 50px;
left: 50px;
}
.blue {
background-color: rgb(13, 13, 152);
top: 100px;
left: 100px;
}
.green {
background-color: rgb(10, 189, 10);
top: 150px;
left: 150px;
}
<div id="container">
<div class="red">Div 1</div>
<div class="blue">Div 2</div>
<div class="green">Div 3</div>
</div>
Не уверен, что я правильно понял задание, вроде просили без z-index. Вот что получилось. В chrome и ff работает.
const item1 = document.querySelector(".item:nth-child(1)");
const item2 = document.querySelector(".item:nth-child(2)");
const item3 = document.querySelector(".item:nth-child(3)");
const item4 = document.querySelector(".item:nth-child(4)");
const items = document.querySelectorAll(".item");
function clearActive() {
items.forEach((item) => {
item.classList.remove("active");
});
}
item1.addEventListener("click", () => {
clearActive();
item1.classList.add("active");
});
item2.addEventListener("click", () => {
clearActive();
item2.classList.add("active");
});
item3.addEventListener("click", () => {
clearActive();
item3.classList.add("active");
});
item4.addEventListener("click", () => {
clearActive();
item4.classList.add("active");
});
.box {
display: flex;
width: 500px;
height: 500px;
align-items: flex-start;
}
.item:nth-child(1) {
background-color: #f25022;
}
.item:nth-child(2) {
background-color: #7fba00;
translate: -100px 100px;
}
.item:nth-child(3) {
background-color: #01a4ef;
translate: -200px 200px;
}
.item:nth-child(4) {
background-color: #c83232;
translate: -300px 300px;
}
.item {
min-width: 200px;
min-height: 200px;
}
.active {
order: 1;
}
.item:nth-child(1).active {
translate: -600px 0;
}
.item:nth-child(1).active+.item {
translate: 100px 100px;
}
.item:nth-child(1).active+.item+.item {
translate: 0 200px;
}
.item:nth-child(1).active+.item+.item+.item {
translate: -100px 300px;
}
.item:nth-child(2).active {
translate: -500px 100px;
}
.item:nth-child(2).active+.item {
translate: 0 200px;
}
.item:nth-child(2).active+.item+.item {
translate: -100px 300px;
}
.item:nth-child(3).active {
translate: -400px 200px;
}
.item:nth-child(3).active+.item {
translate: -100px 300px;
}
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
UPDATE: После замечаний от коллеги @stylok небольшой апдейт. Вот так немного получше. Селекторы классов работают быстрее, однако :nth-child удобнее при сборке кода.
const box = document.querySelector(".box");
box.addEventListener("click", (e) => {
document.querySelector(".box > .active").classList.remove("active");
e.target.classList.add("active");
});
.box {
display: flex;
align-items: flex-start;
width: 500px;
height: 500px;
}
.box>div {
min-width: 200px;
min-height: 200px;
}
.active {
order: 1;
}
.red {
background-color: #f25022;
}
.green {
background-color: #7fba00;
translate: -100px 100px;
}
.blue {
background-color: #01a4ef;
translate: -200px 200px;
}
.brown {
background-color: #c83232;
translate: -300px 300px;
}
.red.active {
translate: -600px 0;
}
.active~.green {
translate: 100px 100px;
}
.green.active {
translate: -500px 100px;
}
.active~.blue {
translate: 0 200px;
}
.blue.active {
translate: -400px 200px;
}
.active~.brown {
translate: -100px 300px;
}
<div class="box">
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
<div class="brown active"></div>
</div>
UPDATE_2: Еще немного улучшил, выяснив, что order
работает и в grid
, но позиционирование элементов при этом облегчается.
const box = document.querySelector(".box");
box.addEventListener("click", (e) => {
if (e.target.parentNode === box) {
document.querySelector(".box > .active").classList.remove("active");
e.target.classList.add("active");
}
});
.box {
display: grid;
grid-template: repeat(5, 1fr)/repeat(5, 1fr);
width: 500px;
height: 500px;
}
.active {
order: 1;
}
.red {
background-color: #f25022;
grid-area: 1/1/3/3;
}
.green {
background-color: #7fba00;
grid-area: 2/2/4/4;
}
.blue {
background-color: #01a4ef;
grid-area: 3/3/5/5;
}
.brown {
background-color: #c83232;
grid-area: 4/4/6/6;
}
<div class="box">
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
<div class="brown active"></div>
</div>
UPDATE3: Спасибо @puffleeck натолкнул на хорошую мысль, только предлагаю использовать не :focus
, а :target
.
.box {
display: grid;
grid-template: repeat(5, 1fr) / repeat(5, 1fr);
width: 500px;
height: 500px;
}
.box>a:target {
order: 1;
}
#red {
background-color: #f25022;
grid-area: 1/1/3/3;
}
#green {
background-color: #7fba00;
grid-area: 2/2/4/4;
}
#blue {
background-color: #01a4ef;
grid-area: 3/3/5/5;
}
#brown {
background-color: #c83232;
grid-area: 4/4/6/6;
}
<div class="box">
<a href="#red" id="red"></a>
<a href="#green" id="green"></a>
<a href="#blue" id="blue"></a>
<a href="#brown" id="brown"></a>
</div>
как на счет фокуса? © джокер
.box {
display: grid; width: 600px; height: 150px;
grid-template: repeat(7, 1fr)/repeat(7, 1fr);
}
.box >*:nth-child(3n+2):focus{
transform: translateZ(1px);
display: list-item;
list-style: 'та да! он приподнялся!' inside;
}
.box >*:nth-child(3n+1):hover{filter: hue-rotate(180deg);}
.box >*:nth-child(3n+1):hover:after{content: "может метод от противно...положного?";}
.box >*:nth-child(3n):active{order: 2;}
.box >*:nth-child(3n):active:before{content: "FREEZE! у меня ORDER на ваш экран!";}
i{background: pink;grid-area: 1/1/3/3;}
.violet{background: violet;grid-area: 6/6/8/8;}
.red {
background-color: #f25022;
grid-area: 2/2/4/4;
}
.green {
background-color: #7fba00;
grid-area: 3/3/5/5;
}
.blue {
background-color: #01a4ef;
grid-area: 4/4/6/6;
}
.brown {
background-color: #c83232;
grid-area: 5/5/7/7;
}
<div class="box">
<i>Feel the magic of pure CSS</i>
<div tabindex='1' class="red"></div>
<div tabindex='2' class="green"></div>
<div tabindex='3' class="blue"></div>
<div tabindex='4' class="brown"></div>
<div tabindex='5' class="violet"></div>
</div>
p.s. в целом тут копия последнего варианта от @Andrei Fedorov, но с некоторыми бонусами :3