Permalink
Browse files

fix(observedom): Callback not being called for changes other than chi…

…ldList changes (#1025)

* fix(observedom): Callback not being called for changes other than node inert/remove

Allow callback to be called based on passed options.

Previously it was only being called if nodes were added or inserted, regardless of which options were passed (i.e. attribute changes, childList, textnode changes, etc.)

This fix remove this restriction.

* Create loose-equal.js

* Update index.js

* Update observe-dom.js

* Update index.js

* Delete loose-equal.js

* Update observe-dom.js

* Update observe-dom.js

* Update observe-dom.js

* Update observe-dom.js
  • Loading branch information...
tmorehouse committed Sep 11, 2017
1 parent 72ffba9 commit 88cfaefb096f0539ad6ea0632eeb56b9b8d6f0de
Showing with 32 additions and 3 deletions.
  1. +32 −3 lib/utils/observe-dom.js
@@ -1,5 +1,6 @@
import { assign } from '../utils/object';
import { assign } from './object';
/**
* Observe a DOM element changes, falls back to eventListener mode
* @param {Element} el The DOM element to observe
@@ -14,14 +15,42 @@ export default function observeDOM(el, callback, opts) {
if (MutationObserver) {
// Define a new observer
const obs = new MutationObserver(mutations => {
if (mutations[0].addedNodes.length > 0 || mutations[0].removedNodes.length > 0) {
let changed = false;
// A Mutation can contain several changes, so we loop through them to see what has changed
// We break out of the loop early if any "significant" change has been detected
for (let i = 0; i < mutations.length && !changed; i++) {
// The muttion record
const mutation = mutations[i];
// Mutation Type
const type = mutation.type;
// DOM Node
const target = mutation.target;
// Previous Value (only for characterData and attributes)
const old = mutation.oldValue;
if (type === 'characterData' && target.nodeType === Node.TEXT_NODE && old !== target.data) {
// We ignore nodes that are not TEXt (i.e. comments, etc) as they don't change layout
// Updating character data with the same value still triggers a mutation
// So we compare the old value to the new value
changed = true;
} else if (type === 'attributes' && target.getAttribute(mutation.attributeName) !== old) {
// Updating an attribute with the same value still triggers a mutation
// So we compare the old value to the new value
changed = true;
} else if (type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) {
// This includes HTMLElement and Text Nodes being added/removed
changed = true;
}
}
if (changed) {
// We only call the callback if a change that could affect layout/size truely happened.
callback();
}
});
// Have the observer observe foo for changes in children
// Have the observer observe foo for changes in children, etc
obs.observe(el, assign({childList: true, subtree: true}, opts));
} else if (eventListenerSupported) {
// Legacy interface. most likely not used in modern browsers
el.addEventListener('DOMNodeInserted', callback, false);
el.addEventListener('DOMNodeRemoved', callback, false);
}

0 comments on commit 88cfaef

Please sign in to comment.