使用Scroll to Next Section jQuery代码报错:Cannot read properties of undefined (reading 'top')求助
排查并修复Scroll to Next Section功能的jQuery报错
错误原因分析
你遇到的Cannot read properties of undefined (reading 'top')错误,本质是尝试读取不存在元素的offset().top属性:
- 当滚动到第一个section向上滚动时,
$(this).prev()返回空的jQuery对象,调用offset()会得到undefined,再读取top就触发类型错误。 - 当滚动到最后一个section向下滚动时,
$(this).next()同样返回空对象,触发相同错误。 - 初始代码未对目标元素的存在性做校验,直接执行滚动逻辑,放大了这个问题。
修复方案及代码
下面是修正后的代码,同时优化了滚轮触发逻辑,避免重复滚动:
(function ($) { // 初始化元素时增加存在性判断,避免元素不存在时报错 var window = $(window), one = $("#one"), two = $("#two"), three = $("#three"), four = $("#four"), oneT = one.length ? one.offset().top : 0, twoT = two.length ? two.offset().top : 0, threeT = three.length ? three.offset().top : 0, fourT = four.length ? four.offset().top : 0; // 滚动函数:先校验目标元素是否存在 function Scroll(div) { if (div instanceof jQuery && div.length > 0) { var tp = div.offset().top; $("html, body").animate({ scrollTop: tp }, 500); } } // 用锁替代tmp变量,避免重复触发滚动 var isScrolling = false; var mousewheelevt = /Firefox/i.test(navigator.userAgent) ? "DOMMouseScroll" : "mousewheel"; $("section").bind(mousewheelevt, function (e) { // 正在滚动时直接返回,阻止重复触发 if (isScrolling) return; isScrolling = true; var evt = window.event || e; evt = evt.originalEvent ? evt.originalEvent : evt; var delta = evt.detail ? evt.detail * -40 : evt.wheelDelta; // 阻止浏览器原生滚动,避免和自定义滚动冲突 e.preventDefault(); if (delta < 0) { Scroll($(this).next()); } else if (delta > 0) { Scroll($(this).prev()); } // 滚动动画结束后解锁,时间和animate的duration一致 setTimeout(() => { isScrolling = false; }, 500); }); })(jQuery);
关键修改点
- 元素存在性校验:在
Scroll函数中增加div instanceof jQuery && div.length > 0判断,确保只有有效元素才执行滚动。 - 初始化安全处理:对
oneT等变量增加length判断,避免页面中不存在对应ID元素时初始化报错。 - 滚动锁机制:用
isScrolling变量替代原来的tmp,更直观地防止一次滚轮操作触发多次滚动。 - 阻止原生滚动:增加
e.preventDefault(),避免浏览器原生滚动和自定义滚动的行为冲突。
内容的提问来源于stack exchange,提问作者Jabir Sayed
相关产品推荐
相关产品推荐

