次のコードを検討してください
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にコンテキストを渡す方法(または正しいスコープを指定する方法)について誰かが提案している場合は、私も感謝します。