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.
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.
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.