Skip to content

Instantly share code, notes, and snippets.

@paceaux
Created June 16, 2017 21:11
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save paceaux/8f8d5d1a57409c5b5f5f2519ceb8ac83 to your computer and use it in GitHub Desktop.
Save paceaux/8f8d5d1a57409c5b5f5f2519ceb8ac83 to your computer and use it in GitHub Desktop.
A promise that can be set on an element, to resolve when that element's attributes have changed
** AttrPromise
* @param {element} DOM element. required
* @param {attributeName} String. Optional. Attribute that is expected to change.
* @param {rejectTime} Int. Optional. Seconds (not ms) to wait before rejecting. 0 means there is no reject time.
* @returns {promise}
*/
function attrPromise(element, attributeName,rejectTime = 0) {
return new Promise((resolve,reject) => {
let hasChanged = false;
const observerConfig = {attributes: true,attributeOldValue:true};
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// if attributeName is given and we have a matching change, disconnect and resolve
if (attributeName && mutation.attributeName == attributeName) {
hasChanged = true;
observer.disconnect();
resolve(element, element.getAttribute(attributeName));
}
// no attributeName is given, but some attribute in general changed, disconnect and resolve
if (!attributeName) {
hasChanged = true;
observer.disconnect();
resolve(element);
}
});
});
// Add a reject time if provided. Doesn't use recurrsion, but should it?
if (rejectTime > 0) {
window.setTimeout(()=>{
if (!hasChanged) {
reject(element);
}
},rejectTime * 100);
}
if (attributeName) observerConfig.attributeFilter =[attributeName];
observer.observe(element, observerConfig);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment