NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
/** * https://github.com/soufianesakhi/node-creation-observer-js * MIT licensed * Copyright (c) 2016 Soufiane Sakhi */ var NodeCreationObserver = function () { var mutationObserver = null; var observedNodeAttribute = "node-creation-observer"; var listeners = {}; var options = { childList: true, subtree: true }; function ListenerContext(removeOnFirstMatch) { this.callbacks = []; this.removeOnFirstMatch = removeOnFirstMatch == undefined ? false : removeOnFirstMatch; } function onMutationCallback(mutationRecordArray) { Object.keys(listeners).forEach(function (selector) { invokeCallbacks(selector); }); } function invokeCallbacks(selector) { var callbacks = listeners[selector].callbacks; var elements = document.querySelectorAll(selector); var newElements = filterNewElements(elements); if (newElements.length > 0) { if (listeners[selector].removeOnFirstMatch) { removeListener(selector); } newElements.forEach(function (element) { callbacks.forEach(function (callback) { callback.call(element, element); }); }); } } function filterNewElements(elements) { var newElements = []; for (var i = 0; i < elements.length; i++) { var element = elements[i]; var attr = element.getAttribute(observedNodeAttribute); if (attr == null) { element.setAttribute(observedNodeAttribute, 1); newElements.push(element); } }; return newElements; } function observe() { if (mutationObserver == null) { mutationObserver = new MutationObserver(onMutationCallback); mutationObserver.observe(document.documentElement, options); } } function removeListener(selector) { delete listeners[selector]; if (Object.keys(listeners).length == 0) { stopObserving(); } } function stopObserving() { if (mutationObserver != null) { mutationObserver.disconnect(); mutationObserver = null; } } return { onCreation: function (selector, callback, removeOnFirstMatch) { if (!listeners[selector]) { listeners[selector] = new ListenerContext(removeOnFirstMatch); } listeners[selector].callbacks.push(callback); observe(); if (document.querySelector(selector) != null) { invokeCallbacks(selector); } }, remove: removeListener, stop: function () { listeners = {}; stopObserving(); } }; } ();