在的addEventListener JS工作不正常(addEventListener in JS

2019-09-03 08:29发布

首先脱脂代码请。

index.html的是:

<html><head><title>Home</title><script src="js/script.js"></script></head>
<body onLoad="init()">

<ul class="sup" id="sup">

    <li class="supitem">
        <a href="#" class="supcont">Home<div class="v"></div></a>
        <ul class="sub">
            <li class="subitem"><a href="#" class="subcont">Home1</a></li>
            <li class="subitem"><a href="#" class="subcont">Home2</a></li>
            <li class="subitem"><a href="#" class="subcont">Home3</a></li>
        </ul>
    </li>

    <li class="supitem">
        <a href="#" class="supcont">Blog<div class="v"></div></a>
        <ul class="sub">
            <li class="subitem"><a href="#" class="subcont">Blog1</a></li>
            <li class="subitem"><a href="#" class="subcont">Blog2</a></li>
            <li class="subitem"><a href="#" class="subcont">Blog3</a></li>
        </ul>
    </li>

</ul>

</body>
</html>

的script.js是:

function init() {
    var sky = 0;
    var sup         = document.getElementById("sup");
    var supitems    = sup.getElementsByClassName("supitem");

    for (var i = 0, ln = supitems.length; i < ln; i++) {
        var supconts = supitems[i].getElementsByClassName("supcont");
        var subs = supitems[i].getElementsByClassName("sub");
        var supcont = supconts[0];

        supcont.innerHTML = "SuperMenu"+i;

        if (subs.length > 0) {
            var sub         = subs[0];

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

            supcont.style.background = "#"+sky+sky+sky;
            sub.style.background = "#"+sky+sky+sky;
            sky += 4;
        }
    }
}

function toggleVisibility(object) {
    object.style.visibility =
        (object.style.visibility == "hidden" ?"visible" :"hidden");
}

当我按下supermenu所有子菜单可见性进行切换我想这样做是。 但我不知道我犯了一个错误。 当我按下Supmenu0,Supmenu1的子菜单切换,不Supmenu1的子菜单。 提前致谢。

PS我觉得这个问题是在的addEventListener。

Answer 1:

这是一个经常被问到的问题,但我会尽量给比我找到了一个更好的解释。 当你传递一个函数作为参数(定义事件处理程序时),JavaScript不评估当时的功能,但它的父级的引用,而不是沿着存储功能scope

该功能没有得到评估,直到触发事件处理程序。 当时,解释器将检查的值subscope 。 由于您在此之后总是会发生for循环已经完成,它总是会找到的最后一个值sub ,即无论sub的时候是for循环完成。 因此,所有的事件侦听器将使用的最后一个值sub

我们可以通过创建一个我们希望的行为关闭 。 替换此:

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

有了这个:

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

这部作品的原因是因为我们与包装新的父每个事件处理程序申报scope通过调用IIFE。 这迫使事件处理程序保留的副本scope的IIFE(被称为创造了一个封闭的内部scope )。 现在,当事件处理程序去寻找localSub ,它将在新的父找到它scope ,这将有我们想要的值。



文章来源: addEventListener in JS not working as expected