Created
July 19, 2021 11:13
-
-
Save cjc/6482e218e19481586e3de9c3cc483372 to your computer and use it in GitHub Desktop.
A reliable (probably) utility for watching attribute changes on immediate children of a dom element
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Watch attribute changes of the immediate children of an element</h1> | |
<p>Utility for easily watching for attribute changes of the immediate children of a given element without paying the performance penalty of <code>subtree</code></p> | |
<ul> | |
<li>On startup, watches any existing children of the asset for attribute changes</li> | |
<li>Also watches for changes to the childlist of the asset</li> | |
<li>When a new asset is added to the asset, starts observing it for attribute changes</li> | |
</ul> | |
<script> | |
var watchChildAttributes = function(element, callback, attributes) { | |
var config = {attributes: true}; | |
if(attributes) { | |
config.attributeFilter = attributes; | |
} | |
var observer = new MutationObserver((records) => { | |
records.forEach(record => { | |
if (record.target == watchee) { | |
record.addedNodes.forEach(node => { | |
observer.observe(node,config); | |
}); | |
record.removedNodes.forEach(node => { | |
//TODO: Probably need to stop observer observing these to prevent memory leak? | |
//Not sure on that. If so, probably need to remove and re-add everything. | |
}); | |
} else { | |
callback(record); | |
} | |
}); | |
}); | |
observer.observe(watchee,{childList:true}); | |
Array.from(watchee.children).forEach((elem) => { | |
observer.observe(elem,config); | |
}) | |
} | |
</script> | |
<!-- Test code for the above --> | |
<style> | |
.a { border: 1px solid red;} | |
.b { border: 1px solid blue;} | |
.c { border: 1px solid green;} | |
.d { border: 1px solid orange;} | |
.e { border: 1px solid purple;} | |
</style> | |
<button id="addchild">Add child</button> | |
<ul id="watchee"> | |
<li class="a"><button class="change">Shuffle class</button> <button class="remove">remove</button> Class history: </li> | |
<li class="b"><button class="change">Shuffle class</button> <button class="remove">remove</button> Class history: </li> | |
<li class="c"><button class="change">Shuffle class</button> <button class="remove">remove</button> Class history: </li> | |
</ul> | |
<script> | |
var classes = ['a','b','c','d','e']; | |
var watchee = document.getElementById('watchee'); | |
document.getElementById('addchild').addEventListener('click',(ev) => { | |
var li = document.createElement('li'); | |
li.innerHTML = `<button class="change">Shuffle class</button> <button class="remove">remove</button> Class history: `; | |
li.className = classes[Math.floor(Math.random() * classes.length)] | |
watchee.append(li); | |
}); | |
document.getElementById('watchee').addEventListener('click',(ev) => { | |
if (ev.target.classList.contains('change')) { | |
ev.target.parentNode.className = classes[Math.floor(Math.random() * classes.length)]; | |
} else if (ev.target.classList.contains('remove')) { | |
ev.target.parentNode.remove(); | |
} | |
}); | |
</script> | |
<script> | |
watchChildAttributes(document.getElementById('watchee'), function(record) { | |
console.log(record.target, record.attributeName); | |
var span = document.createElement('span'); | |
span.innerText = record.target.className + ","; | |
record.target.append(span); | |
},['class']); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment