Javascript 尽管有多个事件侦听器,函数只调用一次
Javascript function called only once despite multiple event listeners
我正在重建我自己的一个网站,专门为了 避免 使用 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()
函数调用,该函数本身通过文档正文标记上的 onload 内联事件侦听器调用 <body onload="Bootstrap()">
。当我刷新页面时,我将这段输出记录到控制台,完全符合预期:
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()
是只打过一次电话!并且它只会将其输出记录到控制台一次。我什至没有通过单击列表项获得额外的输出。当我将光标移到这两个项目上时,我应该会在控制台上打印出一堆乱七八糟的 "It works!"。
我谦虚地请求不使用jQuery的解决方案,谢谢!
您的代码运行良好。我猜你只是误解了控制台输出信息。
参见fiddle:https://jsfiddle.net/3h4y0t01/1/(我只是让输出更明显):
var counter = 0;
function DefBox(ListItem)
{
document.getElementById('out').innerHTML = counter++;
}
我正在重建我自己的一个网站,专门为了 避免 使用 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()
函数调用,该函数本身通过文档正文标记上的 onload 内联事件侦听器调用 <body onload="Bootstrap()">
。当我刷新页面时,我将这段输出记录到控制台,完全符合预期:
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()
是只打过一次电话!并且它只会将其输出记录到控制台一次。我什至没有通过单击列表项获得额外的输出。当我将光标移到这两个项目上时,我应该会在控制台上打印出一堆乱七八糟的 "It works!"。
我谦虚地请求不使用jQuery的解决方案,谢谢!
您的代码运行良好。我猜你只是误解了控制台输出信息。
参见fiddle:https://jsfiddle.net/3h4y0t01/1/(我只是让输出更明显):
var counter = 0;
function DefBox(ListItem)
{
document.getElementById('out').innerHTML = counter++;
}