Random text...">

Detect changes in the order of DOM elements

I have the following code:

<div> <span>Random text</span> <span style="color: red">Random text</span> </div> 

and using the code, I have a 50% chance of changing the order of the elements inside the 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()); } 

This example is simplified. The order is executed by the user using a third-party library that will not tell me if the order has changed, just tell me when it will start and end.

How can I determine if the order of DOM elements has changed? The information that I have inside them cannot be used, because it can be exactly the same as in the example.

Fiddle

+5
source share
2 answers

If you want to check for changes in the DOM, you can use 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); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="id1"> <span>Random text</span> <span style="color: red">Random text</span> </div> 

MutationObserver gives you the ability to check for DOM changes in a specific element without any requirement for code that modifies the DOM.

+15
source

I finally came up with a solution that does what I wanted, and in the way I thought about it, but didn't know how to do it:

  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 changed"); 

The secret is basically to store references to child elements before and after ordering, and then compare them, but NOT a direct link to element.children , since it is updated with the DOM and creates new arrays and has children inside it, current order.

Updated fiddle

+1
source

Source: https://habr.com/ru/post/1259166/


All Articles