Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save cjc/6482e218e19481586e3de9c3cc483372 to your computer and use it in GitHub Desktop.
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
<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