尽管有多个事件监听器,Javascript函数只调用一次

时间:2016-01-18 06:31:02

标签: javascript html javascript-events

我正在重建我自己的一个网站,专门用于避免使用jQuery,因为我使用的很少,因此内存开销不是必需的,而且我不关心支持旧的浏览器(我正在使用的Firefox版本可能是有史以来最早浏览我的网站的浏览器;因此如果他们工作,那么他们将为99.99%的受众工作)。将多个事件侦听器添加到文档中的几个列表项时遇到问题。

HTML片段:

<div class="SubColumn LeftCol grid_12 alpha">
    <div class="InfoBox grid_12 alpha omega">
        <h1>Side Detail</h1>
        <ul>
            <li data-detail-item="Detail item" data-detail-info="Info about the detail item!">Detail item</li>
            <li data-detail-item="Detail item 2" data-detail-info="Info about the second detail item!">Detail item 2</li>
            <li>Detail item</li>
            <li>Detail item</li>
            <ul>
                <li>Detail item</li>
                <li>Detail item</li>
                <li>Detail item</li>
                <li>Detail item</li>
            </ul>
            <li>Detail item</li>
            <li>Detail item</li>
            <li>Detail item</li>
            <li>Detail item</li>
        </ul>
    </div>
</div>

相关的Javascript:

function PrepareDefBoxes()
{
    // I'm using document.querySelectorAll() here as a generic swiss army knife
    // I use it multiple times throughout the script
    // Quite frankly its CSS-selector-syntax input is easier for me to read & maintain
    // CSS-style selectors even work on the custom data-* global attributes ^_^
    var AllDeets = document.querySelectorAll("li[data-detail-item][data-detail-info]");
    // An array of events to add to all the details list items
    // Declared here because I *might* need to add more events; you never know~
    var Events = ["mouseover", "mouseout", "click"];

    // This is a coding trick I've used in C++ and in php
    // If you have nested for loops and all your code is in the innermost loop,
    // you can actually put them all on the same line or on successive lines,
    // then have the scoping braces following the innermost for loop :3
    for(var i = 0; i < AllDeets.length; i++)
    for(var e = 0; e < Events.length; e++)
    {
        AllDeets[i].addEventListener( Events[e], function(event) {
            DefBox(event.target);
        });
        console.log("Added " + Events[e] + " to " + AllDeets[i].innerHTML);
    }
}

function DefBox(ListItem)
{
    console.log("It works!");
}

函数PrepareDefBoxes()由较早的Bootstrap()函数调用,该函数本身通过文档的主体标记la <body onload="Bootstrap()">上的onload内联事件侦听器调用。当我刷新页面时,我将这块输出记录到控制台,完全符合预期:

Added mouseover to Detail item
Added mouseout to Detail item
Added click to Detail item
Added mouseover to Detail item 2
Added mouseout to Detail item 2
Added click to Detail item 2

然而,当我从两个列表项中随机鼠标移除并将鼠标移出时,应该将 THREE 事件侦听器绑定到每个列表项,但函数DefBox()只被调用一次!并且它仅将输出记录到控制台一次。我也没有通过点击列表项来获得额外的输出。当我把光标移到这两个项目上时,我应该弄得一团糟“它有效!”打印到控制台。

我谦卑地请求使用jQuery的解决方案,赞成!

1 个答案:

答案 0 :(得分:1)

您的代码运行正常。我猜你只是误解了控制台输出信息。

请参阅小提琴:https://jsfiddle.net/3h4y0t01/1/(我刚刚使输出更明显):

var counter = 0;
function DefBox(ListItem)
{
    document.getElementById('out').innerHTML = counter++;
}