【问题标题】:on DOMNodeInserted not working as expected?在 DOMNodeInserted 上没有按预期工作?
【发布时间】:2016-11-15 18:59:11
【问题描述】:

基于this question,我写了如下代码:

$(function() {
    $( document ).on('DOMNodeInserted',"span:contains('Suggested Post')", function() {
        console.log("New Suggested Post found");
    })
})

当我向下滚动页面并创建这些元素时,我没有看到我希望看到的控制台消息。但是,如果我在控制台中手动输入$("span:contains('Suggested Post')").length,输出会继续增加。

想法?

@Barmar 请求的片段。它的行为与我的真实场景不太一样,但它仍然不正确......

$(document).on('DOMNodeInserted', "div:contains('Banana')", function() {
  console.log("new banana detected!");
});

$('#btn').on('click', function() {
  var fruit = '';
  switch (Math.floor((Math.random() * 3) + 1)) {
    case 1:
      fruit = 'Apple'
      break;
    case 2:
      fruit = 'Orange'
      break;
    case 3:
      fruit = 'Banana'
      break;
    default:
      fruit = "WTF"
  }
  $('#fakeDocument').append('<div>' + fruit + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fakeDocument">
  <strong>Banana Detector</strong>
  <button id="btn" type="button">Add Banana!</button>
</div>

【问题讨论】:

  • 通过您的委托,您的处理程序仅在创建元素内部匹配选择器的元素时触发,而不是如果创建的元素匹配选择器。
  • 啊啊啊啊,我明白了。有什么修改建议吗?
  • 嗯,我可能错了。 w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInserted 表示 event.target 是要插入的节点,而不是容器。并且 jQuery 将选择器与目标进行匹配。
  • 你能创建一个堆栈片段来演示这个问题吗?
  • 嗯,我确实做到了。我会继续努力的。

标签: javascript jquery dom jquery-events


【解决方案1】:

您需要将委托绑定到正在插入的元素的直接父级。

原因是DOMNodeInserted 事件冒泡了。如果将它绑定到外部容器,它将冒泡到包含 DIV,并且由于 Banana Detector 标题,该 DIV 将匹配 :contains(Banana)。即使您将其移出容器,它也会匹配,因为之前添加的节点包含 Banana

这就是为什么在实际匹配时会触发两次:它会为匹配的新元素触发一次,然后为始终匹配的容器触发一次。

我最初认为event.StopPropagation() 可以解决问题,但事实并非如此。当有实际比赛时,它将防止双重射击。但是当没有匹配时它仍然会触发——事件不会在新元素上触发(因为它不匹配),所以event.stopPropagation() 不会运行,所以它会冒泡到匹配的容器中。

$("#fakeDocument").on('DOMNodeInserted', "div:contains('Banana')", function() {
  console.log("new banana detected!");
});

$('#btn').on('click', function() {
  var fruit = '';
  switch (Math.floor((Math.random() * 3) + 1)) {
    case 1:
      fruit = 'Apple'
      break;
    case 2:
      fruit = 'Orange'
      break;
    case 3:
      fruit = 'Banana'
      break;
    default:
      fruit = "WTF"
  }
  $('#fakeDocument').append('<div>' + fruit + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fakeDocument">
  <strong>Banana Detector</strong>
  <button id="btn" type="button">Add Banana!</button>
</div>

【讨论】:

    猜你喜欢
    • 2019-01-15
    • 2015-03-20
    • 2017-06-29
    • 1970-01-01
    • 2014-03-27
    • 2020-10-13
    • 2016-11-07
    • 2019-11-30
    • 2019-12-20
    相关资源
    最近更新 更多