我遇到了addEventListener()
函数的问题。我正在尝试根据数组中的变量构建一个菜单(我不打算解释为什么这样设置)。
以下是代码:
var _Dirt = document.getElementById("dirt");
_Dirt.addEventListener('mouseover', function () { menuOver(true, this, _dirtY); }, false);
_Dirt.addEventListener('mouseout', function () { menuOver(false, this, _dirtY); }, true);
var _DirtDiv = _Dirt.getElementsByTagName('div')[0];
for (nLink in Men["dirt"]) {
var _lnk = document.createElement('p');
_lnk.className = 'menu';
_lnk.innerHTML = Men["dirt"][nLink][0];
_lnk.addEventListener('click', menuLoop(Men["dirt"][nLink][1]), false);
_DirtDiv.appendChild(_lnk);
_DirtDiv.innerHTML+= '<br />';
}
这是menuLoop函数(如果您担心我没有正确绑定变量:
function menuLoop (n) {
return function () {
menuLink (n);
}
}
现在,令人讨厌的部分是事件监听器在_Dirt
元素上正常工作,但在_lnk
元素上完全没有。即使我将其更改为_lnk.onclick = function () { //something }
,它也无法正常工作(事实上,onclick
属性甚至不会显示在DOM中)。
我有另一个循环函数,它也将一个事件监听器附加到一个元素,并且一个工作完全正常......并且代码非常相似。令人沮丧的是,这段代码过去完美无瑕。我实际上甚至不记得对这段代码进行任何修改。我试图在代码中隔离这个函数,看看我的脚本中是否有任何断点,但问题仍然存在。
如果您需要我的代码的任何其他部分,请告诉我。
答案 0 :(得分:3)
(假设您的数据结构都正确)
你的问题是
_DirtDiv.innerHTML += '<br />';
这基本上采用_DirtDiv
的子节点,将它们序列化为字符串(HTML),连接'<br />'
并将其分配回innerHTML
。浏览器将解析字符串并创建相应的DOM节点。
之前创建的DOM节点的标识丢失,事件处理程序也是如此。此过程会破坏并创建新 DOM节点,这些节点与您之前创建的节点不同。
如果要添加br
节点,请同时使用DOM操作:
_DirtDiv.appendChild(document.createElement('br'));
Chrome控制台中显示节点不同的示例:
> var node = document.createElement('div');
undefined
> node.id = 'foo';
"foo"
> document.body.appendChild(node);
<div id="foo"></div>
> node === document.getElementById('foo');
true // nodes are the same
> document.body.innerHTML += '<br />';
"... long HTML string ..."
> node === document.getElementById('foo');
false // nodes are different