Skip to content

Instantly share code, notes, and snippets.

@o0101
Last active July 27, 2018 12:31
Show Gist options
  • Save o0101/f181ba76e0c9d054afb810e0524afb66 to your computer and use it in GitHub Desktop.
Save o0101/f181ba76e0c9d054afb810e0524afb66 to your computer and use it in GitHub Desktop.
'classchange' Event - with watchClassChange and addEventListener('classchange', ...)
"use strict";
{
const config = {attributes: true};
const observer = new MutationObserver(sendEvent);
const listDiff = new WeakMap();
Object.assign(self,{watchClassChange});
function sendEvent(attrChanges) {
attrChanges
.filter(attrChange => attrChange.attributeName === 'class')
.forEach(classChange => classChange.target.dispatchEvent(
new CustomEvent('classchange',{
bubbles: true,
detail: { changes: getChanges(classChange.target) }
})));
}
function watchClassChange(...elems) {
elems
.map(elem => (observer.observe(elem,config), elem))
.forEach(elem => !listDiff.has(elem) ?
listDiff.set(elem,{classes:new Set(elem.classList)})
: void 0);
}
function getChanges(elem) {
const current = new Set(elem.classList);
const cached = listDiff.get(elem);
const previous = cached.classes;
cached.classes = current;
return {
added: new Set([...current].filter(c => !previous.has(c))),
removed: new Set([...previous].filter(p => !current.has(p)))
};
}
}
@o0101
Copy link
Author

o0101 commented Jul 27, 2018

Using (after it is placed in page context):

watchClassChange(document.body);

document.addEventListener('classchange', x => console.log(x));

document.body.classList.add('abc');

// CustomEvent {isTrusted: false, 
//   detail: {added: Set(1), removed: Set(0)}, type: "classchange", target: body.abc, currentTarget: document, …}

document.body.classList.remove('abc');

// CustomEvent {isTrusted: false, 
//   detail: {added: Set(0), removed: Set(1)}, type: "classchange", target: body, currentTarget: document, …}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment