addEventListener in JS not working as expected

牧云@^-^@ 提交于 2019-12-02 07:01:54

This is a frequently asked question but I will try to give a better explanation than I have found. When you pass a function as a parameter (as when defining your event handler), javascript does not evaluate the function at that time, but instead stores the function along with a reference to its parent scope.

The function does not get evaluated until the event handler is triggered. At that time, the interpreter will check the value of sub in the parent scope. Since this will always happen after your for loop has completed, it will always find the last value of sub, i.e. whatever sub was when your for loop was completed. So all of your event listeners will use the last value of sub.

We can get the desired behavior by creating a closure. Replace this:

supcont.addEventListener("click",function() {
    toggleVisibility(sub); });

with this:

(function(localSub) {
    supcont.addEventListener("click",function() {
        toggleVisibility(localSub);
    });    
})(sub);

The reason this works is because we wrap each event handler declaration with a new parent scope by invoking an IIFE. This forces the event handler to retain a copy of the scope inside the IIFE (called creating a closure over that scope). Now, when the event handler goes looking for localSub, it will find it in the new parent scope and it will have the value we want.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!