检测DOM元素顺序的变化

我有以下代码:

Random text Random text

并且,使用代码,我有50%的机会更改div中元素的顺序。

 $(document).ready(function() { var initial = $("div"); //This might not be ok if (new Date() % 2) //50% chance to randomize order randomizeOrder(); var after = $("div"); //Also this might not be ok //Detect if the order of spans changed if (after != initial) //Definitely won't work console.log("Order changed"); }) function randomizeOrder() { var lastElement = $("div span").last(); $(lastElement).insertBefore($("div span").first()); } 

这个例子过于简单了。 订单由用户使用第三方库完成,该库不会告诉我订单是否实际更改,只需告诉我它何时开始和完成。

如何检测DOM元素的顺序是否实际发生了变化? 我在其中的信息不能使用,因为它可以完全相同,如示例中所示。

小提琴

如果要检查DOM中的更改,可以使用MutationObserver

 $(document).ready(function() { var initial = $("div"); //This might not be ok if (new Date() % 2) { randomizeOrder(); } }); function randomizeOrder() { var lastElement = $("div span").last(); $(lastElement).insertBefore($("div span").first()); } var target = document.getElementById('id1'); // create an observer instance var observer = new MutationObserver(function(mutations) { var changed = false; mutations.forEach(function(mutation) { // You can check the actual changes here }); console.log('Dom Changed'); }); // configuration of the observer: var config = { attributes: true, childList: true, characterData: true }; // pass in the target node, as well as the observer options observer.observe(target, config); 
  
Random text Random text

我终于想出了解决方案,它完成了我想要的和我最初想到的方式,但不知道如何实现它:

  var before = Array.prototype.slice.call($("div")[0].children).map(x => x); if (new Date() % 2) //50% chance to randomize order randomizeOrder(); var after = Array.prototype.slice.call($("div")[0].children).map(x => x); //Detect if the order of spans changed var hasChanged; after.forEach((el, i) => { if (el != before[i]) { hasChanged = true; } }) hasChanged && console.log("Something's changed"); 

秘诀是在排序之前和之后基本上保持element.children引用,然后比较它们,但不是对element.children的直接引用,因为它与DOM一起更新,而是创建新数组,并在其中包含子节点,按当前顺序。

更新小提琴