简体   繁体   English

事件侦听器无法循环工作

[英]Event listener not working in a loop

I'm running into an issue with the addEventListener() function. 我遇到了addEventListener()函数的问题。 I'm trying to build a menu based on variables from an array (I won't bother explaining why it's setup this way). 我正在尝试基于数组中的变量构建菜单(我不会费心解释为什么以这种方式设置菜单)。

Here is the code: 这是代码:

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 />';

}

Here is the menuLoop function (in case you are concerned that I'm not correctly binding the variable right: 这是menuLoop函数(以防您担心我没有正确绑定变量的权利:

function menuLoop (n) {

    return function () {

        menuLink (n);

    }

}

Now, the annoying part is that the event listener is working fine on the _Dirt element, but not at all on the _lnk element. 现在,恼人的是,该事件侦听器工作正常的上_Dirt元素,但不能在所有的_lnk元素。 Even when I change it to to _lnk.onclick = function () { //something } , it won't work (as a matter of fact, the onclick attribute won't even show up in the DOM). 即使当我将其更改为_lnk.onclick = function () { //something } ,它也不起作用(事实上, onclick属性甚至不会显示在DOM中)。

I have another loop function that also attaches an event listener to an element, and that one works perfectly fine...and the code is very similar. 我有另一个循环函数,该函数还将事件侦听器附加到元素上,并且一个函数工作得很好……代码非常相似。 What adds to the frustration is that this code used to work flawlessly. 令人沮丧的是,该代码过去无法完美运行。 I actually don't even recall making any changes to this code at all. 实际上,我什至不记得对此代码进行任何更改。 I tried to isolate this function in the code to see if there were any breakpoints in my script, but it the issue remains. 我试图在代码中隔离此函数,以查看脚本中是否有断点,但问题仍然存在。

Please let me know if you require any other parts of my code. 如果您需要我的代码的其他任何部分,请告诉我。

(This is under the assumption your data structures are all correct) (这是在您的数据结构都正确的前提下)

Your problem is 你的问题是

_DirtDiv.innerHTML += '<br />';

This basically takes the child nodes of _DirtDiv , serializes them to a string (HTML), concatenates '<br />' and assigns it back to innerHTML . 这基本上是_DirtDiv的子节点,将它们序列化为字符串(HTML),连接'<br />'并将其分配回innerHTML The browser will parse the string and create the corresponding DOM nodes. 浏览器将解析字符串并创建相应的DOM节点。

The identity of the DOM node you created before is lost and so is the event handler. 您之前创建的DOM节点的标识将丢失,事件处理程序也会丢失。 This process destroys and creates new DOM nodes which are different than the one you created before. 此过程将破坏并创建新的 DOM节点,这些节点不同于您之前创建的DOM节点。

If you want to add a br node, use DOM manipulation as well: 如果要添加br节点,请同时使用DOM操作:

_DirtDiv.appendChild(document.createElement('br'));

Example from the Chrome console which demonstrates that the nodes are different: 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM