【问题标题】:Click event not propagating up点击事件没有传播
【发布时间】:2014-11-09 23:29:50
【问题描述】:

我在 div 中添加了一个点击事件

div.addEventListener('click', function(event) { ... });

稍后我用 innerHTML 动态添加一个 span。

div.innerHTML = "<span>some text</span>"

现在文本不可点击,这让我很惊讶,因为我认为点击事件会向上传播并触发父 div 上的点击处理程序。怎么回事?

我用 jsfiddle 重新创建了问题。我不明白发生了什么。

http://jsfiddle.net/3n5s3ez9/

【问题讨论】:

  • 您可能需要提供更多信息。这是一个描述您的情况的 jsfiddle:link
  • 谢谢。我实际上在重新创建 jsfiddle 中的错误时遇到了很多困难。我不明白的力量在起作用。

标签: javascript javascript-events


【解决方案1】:

没有什么神奇的事情发生,你看不到点击事件发生,因为点击事件永远不会被触发。原因是浏览器生成事件的行为。我参考this FIDDLE 来解释会发生什么。

  • 在元素首先获得mousedown 和mouseup 之后,在该元素上触发click-event。如果缺少其中之一,则不会执行点击。
  • mouseover 在以下情况下触发:1) 指针进入元素,2) 当指针在元素上移动时,3) 每次 mousedown 元素后,以及 4) 每次 mouseup 元素后。 (只要指针在元素上,Firefox 就会持续触发它,但这并不重要)。
  • 每次我们执行innerHTML = 时,现有的 HTML 都会被删除并创建一个新的 span。在小提琴中,我在 span-text 中添加了一个数字,每次发生时都会增加。

让我们评估一下当你进入 div 并逐步点击 span 时会发生什么:

  • 输入div:mouseover被触发,span由innerHTML创建。这个 span 是数字 0。
  • 在 div 上移动直到到达 span: mouseover 被多次触发,每次都会创建一个新的 span。假设我们最终得到 span20。
  • 点击跨度:首先在现有的span20上触发mousedown。紧接着mouseover 被触发,删除span20 并创建span21。当释放鼠标按钮时,span21 上会触发 mouseup。因为在没有执行点击事件之前,该 span 没有收到mousedown。在 mouseup mouseover 再次触发后,删除 span21 并创建 span22。

如果您缓慢执行操作并观察控制台,则可以轻松跟踪这些步骤。小提琴中的第二个 div 不是单击,而是 mouseup-handler,您会发现每次释放按钮时都会触发该事件。

【讨论】:

    【解决方案2】:

    尝试在 div 上设置背景颜色,以便查看您是否真正点击了预期的内容。我发现 div 通常不在我期望的位置。

    【讨论】:

      【解决方案3】:

      您的问题是“鼠标悬停”侦听器不断在您的 div 上触发,这导致不断添加一个新跨度,然后再次触发它,导致您对跨度元素的点击不会传播。

      我创建了一个只添加一次跨度的小提琴:

      http://jsfiddle.net/3n5s3ez9/59/

      var d = document.getElementById("hello");
      var missionAccomplished = false;
      d.addEventListener("click", function(event) {
          alert(event);
      });
      d.addEventListener("mouseover", function (event) {
          console.log('triggered');
          if (!missionAccomplished) {
              d.innerHTML = "<span>Hello World</span>";
              missionAccomplished = true;
          }
      });
      

      看起来像一个邪恶的循环。

      【讨论】:

        【解决方案4】:

        我认为你需要先获取元素。

        var div = document.getElementsByTagName("div");
        
        div.addEventListener('click', function(event) { ... }, true);
        
        div.innerHTML = "<span>some text</span>"
        

        【讨论】:

          【解决方案5】:

          您的代码非常接近,我做了一些小的调整,效果很好

          HTML:

          Javascript:

            //get elementsByTagName
            //you have to add the [0] index in order for
            //to get the div from the collection of div elements stored
            //in the div variable
            var div = document.getElementsByTagName("div")[0];
          
          
            div.addEventListener('click', function(event) {
          
              alert("it works");
          
          
             });
          
          
          
             div.innerHTML = "<span>Hello World</span>";
          

          【讨论】:

            猜你喜欢
            • 2011-01-15
            • 2011-03-19
            • 2020-09-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-20
            • 1970-01-01
            相关资源
            最近更新 更多