3

次のコードを検討してください

    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();

このコードは、コンテンツ編集可能なdivでDOMの変更(変更)が行われるたびにトリガーされ、observerObj.contextが未定義であることを示すエラーが発生します

ただし、この行のコメントを外す//console.log(this.observer); //->THIS LINEと、エラーは発生せず、期待どおりに機能します。

なんで?

これがJSFiddleです。再現するには、テキストの後にあるcontenteditabledivでEnterキーを押します。


注:循環参照なしでmutationObserverにコンテキストを渡す方法(または正しいスコープを指定する方法)について誰かが提案している場合は、私も感謝します。

4

1 に答える 1

1

Function#bindを使用して正しく保つことができますthis:

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

試してみてください: http://jsfiddle.net/reLr9/

于 2013-02-06T14:09:05.643 に答える