Присвоить класс блоку, оказавшемуся в центральной части браузера при горизонтальной прокрутке
Для упрощения, опишу задачу так. Есть блок, внутри которого прокручиваются горизонтально другие блоки. В каждом из этих блоков абсолютно позиционирован еще один блок в виде цветного квадрата.
Необходимо каждому из этих квадратов присваивать класс .visible в момент, когда этот квадрат докручивается до центра экрана. Центром можно считать область, отстоящую от краёв экрана на 30% слева и справа, вне зависимости от его исходной ширины.
Буду благодарен за подсказку, поскольку в js не силён.
.container{
max-width: 100%;
overflow-x: auto;
white-space: nowrap;
}
.block{
position:relative;
width: 800px;
height: 200px;
display: inline-block;
background-color: rgba(0,0,0,0.2);
}
.square1 {
width:30px;
height:30px;
background:red;
position:absolute;
right:100px;
bottom:80px;
}
.square2 {
width:30px;
height:30px;
background:blue;
position:absolute;
right:200px;
bottom:120px;
}
.square3 {
width:30px;
height:30px;
background:green;
position:absolute;
right:300px;
bottom:50px;
}
.square4 {
width:30px;
height:30px;
background:orange;
position:absolute;
right:400px;
bottom:70px;
}
<div class="container">
<div class="block">
<div class="square1"></div>
</div>
<div class="block">
<div class="square2"></div>
</div>
<div class="block">
<div class="square3"></div>
</div>
<div class="block">
<div class="square4"></div>
</div>
</div>
Ответы (1 шт):
Базовый пример, в котором текущему блоку, занимающему большую часть контейнера, добавляется класс active. А дальше уже можете настроить поведение содержимого.
Если цель не в том, чтобы активировать содержимое блока в поле зрения, а нужна более замысловатая механика, значит, я неправильно понял, извините. (Тогда может быть проще слушать событие scroll у контейнера и, выполнять манипуляции с элементами в зависимости от текущего значения scrollLeft)
const slides = document.querySelectorAll('.block');
slides.forEach((i) => {
if (i) {
const observer = new IntersectionObserver((entries) => {
observerCallback(entries, observer, i)
}, {
threshold: 0.5
});
observer.observe(i);
}
})
const observerCallback = (entries, observer, header) => {
entries.forEach((entry, i) => {
if (entry.isIntersecting) {
Array.from(document.querySelectorAll('.block')).forEach((el) => el.classList.remove('active'));
entry.target.classList.add('active');
}
});
};
.container {
max-width: 100%;
overflow-x: auto;
white-space: nowrap;
}
.block {
position: relative;
width: 800px;
height: 180px;
max-width: 80%;
display: inline-block;
background-color: rgba(0, 0, 0, 0.2);
border: solid 2px transparent;
}
.block.active {
border: solid 2px red;
}
.square1 {
width: 30px;
height: 30px;
background: red;
position: absolute;
right: 100px;
bottom: 80px;
}
.square2 {
width: 30px;
height: 30px;
background: blue;
position: absolute;
right: 200px;
bottom: 120px;
}
.square3 {
width: 30px;
height: 30px;
background: green;
position: absolute;
right: 300px;
bottom: 50px;
}
.square4 {
width: 30px;
height: 30px;
background: orange;
position: absolute;
right: 400px;
bottom: 70px;
}
<div class="container">
<div class="block">
<div class="square1"></div>
</div>
<div class="block">
<div class="square2"></div>
</div>
<div class="block">
<div class="square3"></div>
</div>
<div class="block">
<div class="square4"></div>
</div>
</div>