You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取滚动时用户当前视口内可见的product类产品元素

获取视口内可见product元素的实现方案

问题场景

产品列表滚动时视口固定展示3个产品,所有产品的类名均为product,示例DOM结构如下:

<div class="product">
<span>price:2</span>
</div>

<div class="product">
<span>price:2</span>
</div>

需要拿到当前浏览时刻视口内可见的3个产品元素。

实现方法

方法1:基于getBoundingClientRect遍历判断

这个方案兼容性覆盖所有主流浏览器,逻辑直接,通过元素相对视口的位置信息判断是否处于可见范围:

// 预取所有产品元素、视口高度
const products = document.querySelectorAll('.product');
const viewportH = window.innerHeight;

/**
 * 获取当前视口内可见的产品元素
 * @returns {Element[]} 可见产品集合
 */
function getVisibleItems() {
  return Array.from(products).filter(item => {
    const rect = item.getBoundingClientRect();
    // 元素和视口有相交即判定为可见
    return rect.top < viewportH && rect.bottom > 0;
  });
}

// 滚动时触发获取,加防抖避免高频执行损耗性能
let scrollTimer = null;
window.addEventListener('scroll', () => {
  if (scrollTimer) clearTimeout(scrollTimer);
  scrollTimer = setTimeout(() => {
    const visibleItems = getVisibleItems();
    // 这里拿到的visibleItems就是当前视口内的3个产品,可直接做后续DOM操作
    console.log(visibleItems);
  }, 80);
});

如果需要判定元素完全处于视口内才计入,把过滤条件替换为rect.top >= 0 && rect.bottom <= viewportH即可,你的场景下用默认的相交判断逻辑,就能准确拿到3个可见元素。

方法2:基于IntersectionObserver实现(长列表性能更优)

如果产品列表很长,优先用浏览器原生的相交观察器,不需要绑定scroll事件做高频遍历,性能表现更好:

// 用集合存储当前可见元素,自动去重
const visibleSet = new Set();
const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    entry.isIntersecting 
      ? visibleSet.add(entry.target) 
      : visibleSet.delete(entry.target);
  });
  // 集合转数组就是当前可见的产品列表
  const visibleItems = Array.from(visibleSet);
  console.log(visibleItems);
}, { threshold: 0 });

// 给所有产品元素绑定观察
products.forEach(item => observer.observe(item));

根据项目兼容要求选其中一种用就行,两种方案都能准确拿到视口内的3个.product元素。


内容的提问来源于stack exchange,提问作者Gök Han Güneş

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 04:33:43