addEventListener回调中赋值全局数组后外部if判断无法即时生效问题
问题根因
- 脚本初始化阶段会同步执行所有顶层代码,你的
if判断在页面刚加载时就已经运行完成,此时用户还未点击绑定了事件的元素,function1从未被触发,counterAll[0]的值为undefined,自然不会命中判断条件。 - 全局数组
counterAll本身的跨作用域访问能力是正常的,你遇到的是判断执行时机早于变量赋值时机的时序问题,和变量作用域无关。
额外提示:你的示例代码存在笔误,先通过
getElementById("f1")赋值给变量f1,后续绑定事件却用了未声明的f2,请先修正变量名和DOM元素ID的对应关系,否则事件绑定会直接报错。
可行解决方案
方案1:将判断逻辑移入点击回调
最简单的改造方式是把判断逻辑放到点击回调中,赋值完成后立刻执行判断,保证时序正确:
var counterAll = new Array(); var f2 = document.getElementById("f2"); f2.addEventListener("click", function1); function function1(){ counterAll[0] = 13; // 赋值完成后再执行判断 if(counterAll[0] === 13){ alert("It work's"); } }
方案2:用Proxy监听数组变化(适合多位置监听场景)
如果你需要在多个业务位置响应counterAll的数值变化,不想把所有逻辑都耦合到点击回调里,可以用Proxy代理数组,数值变化时自动触发对应逻辑:
var counterAll = new Array(); // 代理数组监听赋值行为 const counterProxy = new Proxy(counterAll, { set(target, prop, value) { target[prop] = value; // 赋值完成后自动触发匹配逻辑 if (prop === '0' && value === 13) { alert("It work's"); } return true; } }); var f2 = document.getElementById("f2"); f2.addEventListener("click", function1); function function1(){ // 对代理对象赋值即可触发监听逻辑 counterProxy[0] = 13; }
方案3:轮询检测(仅做参考,不推荐生产环境使用)
如果实在不想改动原有点击回调的逻辑,可以用定时器定期检查数值变化,该方案性能损耗较高,仅适合临时调试使用:
var counterAll = new Array(); var f2 = document.getElementById("f2"); f2.addEventListener("click", function1); function function1(){ counterAll[0] = 13; } // 每100毫秒检查一次数值 const checkTimer = setInterval(() => { if(counterAll[0] === 13){ alert("It work's"); clearInterval(checkTimer); // 命中后清除定时器避免重复执行 } }, 100);
内容的提问来源于stack exchange,提问作者Ibrahim Hossain
相关产品推荐
相关产品推荐

