【问题标题】:How can I get the old parent of a MutationObserver's removedNode, before it was removed?如何在 MutationObserver 删除节点被删除之前获取它的旧父级?
【发布时间】:2016-05-05 13:01:27
【问题描述】:

我整理了一个示例,在动态变化的 DOM 中,我将叶节点着色为红色,分支为蓝色。为了处理节点删除,我跟踪每个节点上的子 count。当它达到零时,该节点成为叶节点。问题是我需要减少每个删除节点的所有祖先的计数。 MutationObserver 似乎在 节点已从 DOM 中删除之后给出了删除事件,因此它没有父节点。有什么方法可以让我在移除之前仍然得到原来的父母吗?

在我的应用程序中,我将过滤器应用于某些节点,并且不想通过让父节点和子节点都带有过滤器来进行两次过滤。我正在使用上述方法处理动态 DOM。它也是一个浏览器扩展,需要尽可能便宜且不显眼地处理任意内容。

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    $(mutation.addedNodes).find('*').addBack().each(function(i, node) {
      //all added nodes come through here
      if ($(node).data('count')) {
        //a child has already been processed so must be a branch
        $(node).addClass('branch');
      } else {
        //set ancestors as .branch and increment their count
        $(node).parents('div').each(function() {
          $(this).removeClass('leaf').addClass('branch');
          $(this).data('count', ($(this).data('count') || 0) + 1);
        });
        
        //no children have been processed so must be a leaf
        $(this).addClass('leaf');
      }
    });
    $(mutation.removedNodes).find('*').addBack().each(function(i, node) {
      //FIXME: parentNode is null
      console.log(node, node.parentNode);
      
      //decrement ancestor counts and set as leaf if zero
      $(node).parents().each(function() {
        $(this).data('count', $(this).data('count') - 1);
        if ($(this).data('count') == 0)
          $(this).removeData('count').removeClass('branch').addClass('leaf');
      });

    });
  });
});

observer.observe(document, {
  subtree: true,
  childList: true
});

//for debugging counts
$(document).on("mouseenter", "div", function() {
  $(this).attr('title', $(this).data('count'));
});

$(document.body).append('<div>');

//add some divs
window.setTimeout(function() {
  $('div').eq(0).append('<div><div></div></div>');
  $('div').eq(0).append('<div>');
}, 500);

//remove divs
window.setTimeout(function() {
  $('div').eq(2).remove();
}, 1000);
div {
  min-height: 60px;
  border: 1px solid black;
  margin: 10px;
  background-color: white;
}
.branch {
  background-color: #a3aff5;
}
.leaf {
  background-color: #f5a3a3;
}
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

【问题讨论】:

    标签: javascript jquery tree mutation-observers


    【解决方案1】:

    您可以使用MutationRecord.target 属性,如

    var id = 0;
    $('div').click(function(e) {
      $(this).remove();
      e.stopPropagation();
    }).attr('id', function() {
      return 'div-' + ++id
    });
    
    var observer = new MutationObserver(function(mutations) {
    
      mutations.forEach(function(mutation) {
        if (mutation.removedNodes.length) {
          console.log('mutation', mutation, mutation.target.id);
          snippet.log('deleted from node: ' + mutation.target.tagName + '[' + (mutation.target.id || '') + ']')
        }
      });
    
    });
    
    observer.observe(document, {
      subtree: true,
      childList: true
    });
    div {
      padding: 10px;
      border: 1px solid grey;
      margin-bottom: 5px;
    }
    div:last-child {
      margin-bottom: 0;
    }
    <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <section id="ct">
      <div></div>
      <div></div>
      <div></div>
      <div>
        <div></div>
        <div></div>
      </div>
    </section>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2021-05-10
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多