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

导航栏图片滚动匹配视口区域切换失效问题求助

导航栏图片滚动切换失效问题

我已经实现了导航栏图片的鼠标悬停切换效果,但当页面滚动到对应ID的区域进入视口时,无法触发相同的图片切换。悬停功能正常,滚动切换无效果。


现有代码

导航栏代码

<div class="number"><a href="#3"><img class="ai" src="https://unsplash.com/photos/Z1wosLgwGT8" onmouseover="this.src='https://unsplash.com/photos/q98u_gIRs6I'" onmouseout="this.src='https://unsplash.com/photos/Z1wosLgwGT8'" alt="3"></a></div>

页面区域代码

<div class="test" id="1"></div>
<div class="test" id="2"></div>
<div class="test" id="3"></div>
<div class="test" id="4"></div>

已编写的JavaScript代码

const testDiv = document.querySelector("#3");
const aiImg = document.querySelector(".ai");

window.addEventListener("scroll", function() {
  const viewportHeight = window.innerHeight;
  const divTop = testDiv.getBoundingClientRect().top;
  const divBottom = testDiv.getBoundingClientRect().bottom;
  
  if (divTop <= viewportHeight && divBottom >= 0) {
    aiImg.src = "https://unsplash.com/photos/q98u_gIRs6I";
  }
});

问题原因及修复方案

核心问题

  1. 纯数字ID的兼容性隐患:虽然HTML5允许数字开头的ID,但部分环境下querySelector("#3")可能无法正确匹配元素,容易引发选择器失效。
  2. 缺少离开视口的还原逻辑:当前代码只处理了进入视口的切换,未考虑元素离开视口时的图片还原,导致图片一旦切换就无法恢复初始状态。
  3. 滚动事件性能问题:滚动事件触发频率极高,直接在回调中执行DOM操作可能造成页面卡顿。

修复后的代码

调整HTML(优化ID命名)

<!-- 导航栏 -->
<div class="number"><a href="#section-3"><img class="ai" src="https://unsplash.com/photos/Z1wosLgwGT8" onmouseover="this.src='https://unsplash.com/photos/q98u_gIRs6I'" onmouseout="this.src='https://unsplash.com/photos/Z1wosLgwGT8'" alt="3"></a></div>

<!-- 页面区域 -->
<div class="test" id="section-1"></div>
<div class="test" id="section-2"></div>
<div class="test" id="section-3"></div>
<div class="test" id="section-4"></div>

优化后的JavaScript

const testDiv = document.querySelector("#section-3");
const aiImg = document.querySelector(".ai");
// 统一维护图片地址,避免重复代码
const originalSrc = "https://unsplash.com/photos/Z1wosLgwGT8";
const hoverSrc = "https://unsplash.com/photos/q98u_gIRs6I";

// 节流函数:限制滚动事件触发频率,优化性能
function throttle(func, delay = 100) {
  let timer = null;
  return function() {
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, arguments);
        timer = null;
      }, delay);
    }
  };
}

function handleViewportCheck() {
  const viewportHeight = window.innerHeight;
  const rect = testDiv.getBoundingClientRect();
  const isInViewport = rect.top <= viewportHeight && rect.bottom >= 0;
  
  aiImg.src = isInViewport ? hoverSrc : originalSrc;
}

// 绑定节流后的滚动事件
window.addEventListener("scroll", throttle(handleViewportCheck));
// 页面加载时执行一次,处理初始状态
handleViewportCheck();

进阶优化方案(使用原生API)

可以用浏览器原生的IntersectionObserver替代滚动事件监听,性能更优且代码更简洁:

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    aiImg.src = entry.isIntersecting ? hoverSrc : originalSrc;
  });
}, { threshold: 0.1 }); // 元素10%进入视口时触发

observer.observe(testDiv);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:52:40