JS循环绑定点击事件时提示HTML元素undefined是什么原因?
问题根因
核心报错原因是var关键字的变量作用域特性导致的:
var声明的变量只有函数级作用域,不存在块级作用域,整个循环过程中只会生成一个i变量- 点击事件是异步触发的,触发时循环已经执行完毕,此时
i的值固定为anchors.length,超出了数组的下标范围 - 取值
anchors[i]得到undefined,对应的$("#undefinedStrip")选择不到任何元素,调用offset()返回undefined,读取top属性自然就会报错
解决方案
方案1:使用let声明迭代变量(推荐,ES6+环境适用)
把循环里的var i改成let i即可,let支持块级作用域,每次循环都会生成独立的i变量绑定到当前迭代的作用域,点击事件触发时能取到对应轮次的正确值:
for (let i = 0; i < anchors.length; i++) { $("." + anchors[i]).click(function() { $("body").animate({ scrollTop: $("#" + anchors[i] + "Strip").offset().top }, 1000); }); }
方案2:使用立即执行函数做闭包缓存(兼容ES5低版本环境)
如果需要兼容不支持ES6的旧环境,可以用IIFE把每次循环的i值缓存到独立的函数作用域里:
for (var i = 0; i < anchors.length; i++) { (function(index) { $("." + anchors[index]).click(function() { $("body").animate({ scrollTop: $("#" + anchors[index] + "Strip").offset().top }, 1000); }); })(i) }
方案3:用自定义属性优化绑定逻辑(更高效,避免循环绑定事件)
给所有触发点击的元素加上统一的类名比如anchor-trigger,同时给元素加data-anchor属性存储对应的锚点标识,一次绑定就能覆盖所有元素:
<!-- 元素示例 --> <div class="anchor-trigger" data-anchor="about">关于我们</div> <div id="aboutStrip">关于我们内容区块</div>
$(".anchor-trigger").click(function() { const targetAnchor = $(this).data("anchor") $("body").animate({ scrollTop: $("#" + targetAnchor + "Strip").offset().top }, 1000) })
内容的提问来源于stack exchange,提问作者theoutstandingme
相关产品推荐
相关产品推荐

