VanillaJS如何定位滚动容器可视区域内的中间子元素
问题根因
原有判断逻辑仅校验元素顶部位置 >= 容器高度的1/2,所有位于中间线下方的元素都会满足该条件,因此会被批量添加midsegment类。
修正后代码
function findMiddleSegment() { const segmentListContainer = document.querySelector('.container'); const containerRect = segmentListContainer.getBoundingClientRect(); // 计算容器可视区域的中间Y坐标(相对于视口) const containerMidY = containerRect.top + containerRect.height / 2; const segments = document.querySelectorAll('.segment'); // 先清空所有元素的midsegment类,避免样式残留 segments.forEach(segment => segment.classList.remove('midsegment')); let currentMidSegment = null; // 遍历找到覆盖中间线的元素 for (const segment of segments) { const segRect = segment.getBoundingClientRect(); // 判断中间线是否落在当前元素的上下边界之间 if (containerMidY >= segRect.top && containerMidY <= segRect.bottom) { currentMidSegment = segment; break; } } // 给匹配到的中间元素加类、获取ID if (currentMidSegment) { currentMidSegment.classList.add('midsegment'); const midSegmentId = currentMidSegment.id; // 此处可添加ID对应的业务逻辑 } } function handleDOMChange() { findMiddleSegment(); const segmentListContainer = document.querySelector('.container'); // 可选优化:添加防抖避免滚动时高频触发计算,提升性能 let scrollTimer = null; segmentListContainer.addEventListener('scroll', () => { clearTimeout(scrollTimer); scrollTimer = setTimeout(findMiddleSegment, 50); }); }
逻辑说明
- 以容器可视区域的中间线Y轴坐标为匹配基准,仅当元素的上下边界刚好覆盖这条中间线时,才会被判定为中间元素,保证同一时间只有一个元素符合条件
- 兼容所有边界场景:仅2个元素时,只要第二个元素覆盖中间线就会被选中;滚动时会实时计算匹配中间元素
- 可选的防抖逻辑可根据实际需求调整延迟时长,滚动场景下能有效减少不必要的计算消耗
内容的提问来源于stack exchange,提问作者Marcin
相关产品推荐
相关产品推荐

