我有一个这样的设置
<div class=“container”>
<div class=“segment segment1”></div>
<div class=“segment segment2”></div>
<div class=“segment segment3”></div>
.
.
.
<div class=“segmentN”></div>
</div>
其中N是用户定义的数字,所以list是动态的。对于容器,我已经应用样式将其显示为网格,因此每次列表都显示3个项目,列表是可滚动的。我的问题是,我怎么能通过VanillaJS找到元素是在容器的中间?如果页面中有3个元素,它应该选择第二个,当向下滚动时,它应该选择在容器中间的元素,每次应用一些样式,除了抓取它的id。如果有2个元素,它也应该选择第2项。我正在考虑检查容器的高度,将其除以一半并检查元素的位置,如果它在范围内。到目前为止,我可以用js
编写这段代码function findMiddleSegment() {
//selecting container
const segmentListContainer = document.querySelector(`.container`);
const rect = segmentListContainer.getBoundingClientRect();
//selecting all divs
const segments = document.querySelectorAll(`.segment`);
segments.forEach( (segment) => {
const location = segment.getBoundingClientRect();
if( (location.top >= rect.height / 2) ){
segment.classList.add(`midsegment`);
} else {
segment.classList.remove(`midsegment`);
}
});
}
但是它不起作用。它在中间找到元素,但也为中间段以下的每个其他元素应用样式。我在stackoverflow上读了一些答案,但是找不到任何解决我问题的方法。
编辑除了我的问题之外,我还添加了额外的函数来显示如何调用它。
function handleDOMChange() {
findMiddleSegment(); //for "first run" when doc is loaded
const segmentListContainer = document.querySelector(`.container`);
segmentListContainer.addEventListener('scroll', findMiddleSegment);
}
一个非常简单的方法是使用交集观察者:
const list = document.querySelector('ul'),
idDisplay = document.querySelector('p b');
const observer = new IntersectionObserver(
highlightMid,
{
root: list,
rootMargin: "-33.33% 0%",
threshold: .5
}
);
function makeList() {
list.innerHTML = '';
observer.disconnect();
const N = document.querySelector('input').value;
for (let i = 0; i < N;) {
const item = document.createElement('li');
item.id = `i_${++i}`;
item.textContent = `Item #${i}`;
list.append(item);
observer.observe(item);
}
};
function highlightMid(entries) {
entries.forEach(entry => {
entry.target.classList
.toggle('active', entry.isIntersecting);
})
const active = list.querySelector('.active');
if (active) idDisplay.textContent = '#' + active.id;
}
ul {
width: 50vw;
height: 50vh;
margin: auto;
padding: 0;
overflow-y: auto;
border: solid 1px;
}
li {
box-sizing: border-box;
height: 33.33%;
padding: .3em 1em;
list-style: none;
transition: .3s;
}
.active {
background: #6af;
}
<i>Make a list of:</i>
<input type="number" min="2" placeholder="number of items">
<button onclick="makeList()">make</button>
<p>Active id is <b>yet to set</b></p>
<ul></ul>
如果容器内部只有一个段列表,则更容易计数元素的子元素并找到中间元素。
const segmentListContainer = document.querySelector(`.segmentListContainer`);
const midSegmentIndex = Math.floor(segmentListContainer.children.length / 2) - 1;
let midSegment = segmentListContaner.children[midSegmentIndex];
midSegment.classList.add('midsegment');
公立小学你的代码在每个元素的类名后面加上'mdsegment'的原因是因为你写的这行条件语句。
if(location.top >= rect.height / 2){
segment.classList.add(`midsegment`);
}
就像这样。你可以用数学。圆的,数学。天花板或数学。就像我一样。这是因为querySelectorAll返回一个数组,您可以使用数组。length来计算数组中项目的总数,然后使用for循环遍历所有片段,并根据Math语句放置类。(圆形,地板或天花板)根据您的需要。
const container = document.querySelector(".container");
const segments = container.querySelectorAll(".segment");
const middleSegment = Math.floor(segments.length / 2);
for (let index = 0; index < segments.length; index++) {
segments[middleSegment].classList.add("middle-segment");
}
.middle-segment{
background-color: red;
}
<div class="container">
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
</div>
你不需要javascript。CSS会做
.container {
width: 350px;
}
.container .segment {
width: 100px;
height: 100px;
float: left;
background-color: #EEE;
border: 1px dotted gray;
margin: 3px;
text-align: center;
color: silver;
}
.segment:nth-child(3n-1) {
background-color: aquamarine;
color: black;
}
<div class="container">
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
<div class="segment">segment</div>
</div>