3

Please consider the following code

    var factory = function (element, opts) {
        var MutationObserverController = function (element, opts) {
            var defaults = {
                subtree: true,
                childList: true,
                characterData: true
            };

            this.options = $.extend({}, defaults, opts);
            this.watchedElement = element;

            this.observer = new MutationObserver(this.mutationObserver);
            this.observer.context = this;
            //console.log(this.observer); //->THIS LINE
        };

        MutationObserverController.prototype.connect = function () {
            this.observer.observe(this.watchedElement, this.options);
        };

        MutationObserverController.prototype.disconnect = function () {
            this.observer.disconnect();
        };

        MutationObserverController.prototype.mutationObserver = function (mutations, observerObj) {
            var ctx = observerObj.context;
            ctx.disconnect();
            mutations.forEach(function (m) {
                console.log(m);
            });
            ctx.connect();
        };

        return new MutationObserverController(element, opts);
    };

    var mutOb = factory($('#myEditor').get(0), {});
    mutOb.connect();

This code is triggered everytime a DOM modification (mutation) is done in a contenteditable div and it prduces an error stating that observerObj.context is undefined.

However, if I uncomment this line //console.log(this.observer); //->THIS LINE, no error is produced and it works as expected.

Why?

Here's the JSFiddle. To reproduce, press ENTER in the contenteditable div, after the text.


Note: If someone has a suggestion in how to pass context to the mutationObserver without a circular reference (or give the correct scope), I would be grateful too.

Tivie
  • 18,864
  • 5
  • 58
  • 77
  • I've played a bit with JSFIddle. Sometimes it works without console.log, sometimes it doesn't. That's pretty strange. I use Chromium 22.0.1229.94 – Artem Sobolev Feb 06 '13 at 13:54
  • @Barmaley.exe Yes, I've noticed this also... Can't really understand why – Tivie Feb 06 '13 at 14:01

1 Answers1

1

You can use Function#bind to keep correct this:

this.observer = new MutationObserver(this.mutationObserver.bind(this));

Try it: http://jsfiddle.net/reLr9/

Artem Sobolev
  • 5,891
  • 1
  • 22
  • 40
  • Indeed. Although the idea was to bind the function later to another object (the actual object that triggered the event). I supose I can refactor the code and use some sort of Event Mediator but it's really strange. Maybe it's a bug in the Mutation Observer – Tivie Feb 06 '13 at 14:17
  • It seems it's chrome/chromium related. I was sure I could reproduce it on firefox... – Tivie Feb 06 '13 at 14:19