Skip to content

Lightweight implementation of MutationObserver / DOM Mutation Observers as an Ember component.

License

Notifications You must be signed in to change notification settings

RyanNerd/ember-cli-dom-observer

Repository files navigation

ember-cli-dom-observer

Implementation of MutationObserver / DOM Mutation Observers as an Ember component.

Detailed Documentation

Uses

  • Browser extensions - You've created a browser extension in Ember and need to monitor changes to the DOM to trigger your extension.
  • Overcome HTML shortcomings by allowing you to monitor changes to attributes, elements and nodes (anything in the DOM).
  • Hook into 3rd party components that you are otherwise unable to see changes that these components make to the DOM (e.g. Jquery Addon).
  • Troubleshooting - Examine misbehaving components as they change within the DOM.

Features

  • Fast DOM change event capture.
  • Capture snapshot DOM change comparison events for specific elements.
  • Any DOM change can be captured including very complex events.
  • Finite control allowing you to select what elements are observed and what changes to monitor.

How does this work?

By using the Ember component methodology to wrap a MutationObserver around an HTML element (see example code below).

Further information on MutationObserver can be found in these excellent blog posts:

Addon Installation

  • ember install ember-cli-dom-observer

Requirements

  • Ember 2.15
    • Older Ember 2.x versions may work but this component has not been used/tested with previous versions.
    • If you are using Ember 1.x or your version of Ember does not work with this component then use this Addon instead.
  • Only works with modern web browsers
    • Chrome 49+
    • Edge 14+
    • Firefox 52+
    • IE 11
    • Opera 46+
    • Safari 10.1+

Addon Usage

{{#mutation-observer
    handleMutations=(action "handleMutations")
    attributes=true
    childList=true
    characterData=true
    subtree=true
    attributeFilter='["JSON","string","array"]'
}}
  <ol contenteditable>
    <li>Click here and press enter</li>
  </ol>
{{/mutation-observer}}
  import Ember from 'ember';
  export default Ember.Component.extend({

  actions: 
  {
    /**
     * MutationObserver triggered events action handler
     * 
     * @param {MutationRecord[]} mutationRecords The triggered mutation records
     * @param {MutationObserver} observer
     */
    handleMutations(mutationRecords, observer) {
      // Do something with mutation records
    }
  }
})

In the example above MutationRecords will be sent to the handleMutations() action function when any changes (e.g. new <LI> node was added) to the ordered list occur.

This Addon can also be used as a standalone component by using the targetId property to indicate the element to be observed as in the example below.

{{mutation-observer
handleMutations=(action "handleMutations")
attributes=false
childList=false
characterData=true
subtree=true
targetId="btn"}}

<button id="btn" contenteditable="true">Click Here to Change Button Text</button>
<p>Button Text: {{buttonText}}</p>
  import Ember from 'ember';
  export default Ember.Component.extend(
{
  buttonText: null,

  actions: 
  {
    handleMutations(mutations, observer) {
      let self=this;
      mutations.forEach(function (mutation) 
      {
        if (mutation.type === 'characterData') {
          self.set('buttonText', mutation.target.textContent);
          observer.takeRecords(); // Empty the mutation queue.
        }
      });
    }
  }
})

IMPORTANT NOTE: It is possible to have more than one observed element (multiple mutation-observer components) on a page and have each observed element use the same mutationHandler action.

However this is not best practice, and can cause recursion issues.

Each element you wrap in a component or set as the targetId should have an individual mutationHandler action. See the code in tests/dummy/app/components/example-mutation.js for an examples of best practice and bad practice.

Installation

  • git clone https://github.com/RyanNerd/ember-cli-dom-observer.git
  • npm install or yarn install

Running Examples