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

如何用Intersection Observer确定动态缩放元素的活跃项?

解决方案

要实现需求,核心是利用IntersectionObserverEntry的intersectionRatio属性获取元素的可见比例,同时跟踪元素进入视口的时间来处理多个完全可见的情况。以下是修改后的完整代码:

const options = {
  root: document.getElementById('viewport'),
  // 元素可见性变化即触发回调,无需限制阈值范围
  threshold: 0,
};

const observer = new IntersectionObserver(onIntersect, options);
const items = document.getElementsByClassName('item');
// 维护当前可见元素集合,存储元素与对应可见比例
const visibleItems = new Map();

for (const item of items) {
  observer.observe(item);
}

let activeItem = null;

function onIntersect(entries, observer) {
  entries.forEach((entry) => {
    const item = entry.target;
    if (entry.isIntersecting) {
      // 记录元素进入视口的时间戳,用于判断"最新出现"
      item.dataset.entryTime = Date.now();
      visibleItems.set(item, entry.intersectionRatio);
    } else {
      // 元素退出视口,从可见集合中移除
      visibleItems.delete(item);
    }
  });

  // 无可见元素时直接返回
  if (visibleItems.size === 0) {
    activeItem = null;
    return;
  }

  // 将可见元素转为数组,开始筛选活跃项
  const itemsArray = Array.from(visibleItems.entries());

  // 第一步:筛选所有完全可见(可见比例为100%)的元素
  const fullyVisibleItems = itemsArray.filter(([item, ratio]) => ratio === 1);

  if (fullyVisibleItems.length > 0) {
    // 多个完全可见时,选取进入视口时间最晚的元素
    activeItem = fullyVisibleItems.sort((a, b) => {
      return b[0].dataset.entryTime - a[0].dataset.entryTime;
    })[0][0];
  } else {
    // 无完全可见元素时,选取可见比例最高的元素
    activeItem = itemsArray.sort((a, b) => b[1] - a[1])[0][0];
  }

  // 可在此添加活跃项的样式切换逻辑,示例:
  // document.querySelectorAll('.item').forEach(el => el.classList.remove('active'));
  // activeItem.classList.add('active');
}

关键逻辑说明

  • 可见元素跟踪:用Map结构visibleItems维护当前可见元素及其可见比例,元素进入视口时添加、退出时移除,避免无效遍历。
  • 进入时间记录:通过元素的dataset.entryTime存储进入视口的时间戳,确保多个完全可见元素能区分“最新出现”的对象。
  • 分层筛选逻辑:
    1. 优先筛选完全可见元素,存在时按进入时间倒序排序取第一个。
    2. 无完全可见元素时,按可见比例倒序排序取比例最高的元素。
  • 回调触发时机:将threshold设为0,确保元素可见性发生任何变化时都触发回调,保证数据实时更新。

内容的提问来源于stack exchange,提问作者Dia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:52:21