2013-04-10 19 views
4

Here jsFiddle to test sample自定義事件文檔onContentChange

我目前正在寫一個jQuery代碼段來處理DOM的任何HTML內容的改變「觸發」任何的jQuery domManip功能(擴展一些功能)。不知道這是做這件事的最佳方式,所以任何建議都會受到歡迎。 如果綁定到文檔,此代碼段按預期工作。但是,如果我嘗試將其綁定到特定元素,我正面臨着一些功能如.remove()的問題。也許這是由於自定義事件不使用正常的傳播行爲,但我真的不確定。

這是一個工作示例中,我結合「contentChange」事件記錄,工程跨瀏覽器作爲我可以測試:{火狐,IE9,Chrome和Safari Win7的下}

; 
(function ($) { 
    $.fn.contentChange = function (types, data, fn) { 
     return this.on('contentChange', types, null, data, fn); 
    }; 
    var oDomManip = $.fn.domManip, 
     oHtml = $.fn.html, 
     oEmpty = $.fn.empty, 
     oRemove = $.fn.remove, 
     extendFct = function (oFct, sender, args) { 
      return oFct.apply(sender, args), $.event.trigger('contentChange'); 
      //=>if testing specific element (#test) use instead following line 
      //return oFct.apply(sender, args), $(sender).trigger('contentChange'); 
     }; 
    $.fn.domManip = function() { 
     extendFct(oDomManip, this, arguments) 
    }; 
    $.fn.html = function() { 
     extendFct(oHtml, this, arguments) 
    }; 
    $.fn.empty = function() { 
     extendFct(oEmpty, this, arguments) 
    }; 
    $.fn.remove = function() { 
     extendFct(oRemove, this, arguments) 
    }; 

})(jQuery); 

使用: $.event.trigger('contentChange')觸發自定義事件。

調用喜歡它:

$(document).contentChange(function() { 
    console.log("onContentChange") 
}); 

但是,如果我使用:

$('#test').contentChange(function() { 
    console.log("onContentChange") 
}); 

自定義事件不會被觸發。 因此,一個特定的元素上觸發一個自定義事件,我可以引發這樣的:

$(sender).trigger('contentChange'); 

但現在,打電話給自我或兒童remove()方法不觸發我的自定義事件。 我可以理解,如果我刪除元素,則不會調用事件回調函數,但爲什麼在刪除子元素時它不會調用它(如果它綁定到文檔,它會工作)?

期待此行進行自定義事件冒泡爲「#TEST」:

$('#test').find('div:first').remove(); 

有什麼辦法來觸發綁定到特定的元素這個自定義事件操縱這個元素和時/或其子女?

+0

不應'$ .event.trigger( 'contentChange')'來代替上觸發事件元件?如被操縱的那個?側記,這是livequery用來獲得類似效果的技術,我建議查看livequery是如何實現可能的改進的。 – 2013-04-10 14:13:55

+0

爲什麼你不使用[DOMSubtreeModified](http://stackoverflow.com/questions/2844565/is-there-a-jquery-dom-change-listener) – alexP 2013-04-10 14:21:32

+0

@alexP http://stackoverflow.com/questions/ 6659662 /爲什麼這是domsubtree修改事件棄用在DOM級別3 – 2013-04-10 14:24:26

回答

0

我帶有稍微修改過的版本,這似乎很好地工作達到我的目的。 需要優化.on()方法擴展,所以請隨時分享您的反饋。

從這裏啓發:https://groups.google.com/forum/?fromgroups=#!topic/jquery-dev/ZaMw2XB6wyM

感謝威爾 - 斯塔基

Here jsFiddle

;(function ($) { 
    var fctsToObserve = { 
     append: [$.fn.append, 'self'], 
     prepend: [$.fn.prepend, 'self'], 
     remove: [$.fn.remove, 'parent'], 
     before: [$.fn.before, 'parent'], 
     after: [$.fn.after, 'parent'] 
    }, fctsObserveKeys = ''; 
    $.each(fctsToObserve, function (key, element) { 
     fctsObserveKeys += "hasChanged." + key + " "; 
    }); 
    var oOn = $.fn.on; 
    $.fn.on = function() { 
     if (arguments[0].indexOf('hasChanged') != -1) arguments[0] += " " + fctsObserveKeys; 
     return oOn.apply(this, arguments); 
    }; 
    $.fn.hasChanged = function (types, data, fn) { 
     return this.on(fctsObserveKeys, types, null, data, fn); 
    }; 
    $.extend($, { 
     observeMethods: function (namespace) { 
      var namespace = namespace ? "." + namespace : ""; 
      var _len = $.fn.length; 
      delete $.fn.length; 
      $.each(fctsToObserve, function (key) { 
       var _pre = this; 
       $.fn[key] = function() { 
        var target = _pre[1] === 'self' ? this : this.parent(), 
         ret = _pre[0].apply(this, arguments); 
        target.trigger("hasChanged." + key + namespace, arguments); 
        return ret; 
       }; 
      }); 
      $.fn.length = _len; 
     } 
    }); 
    $.observeMethods() 
})(jQuery); 
1

您需要在被修改的元素上觸發事件。

http://jsfiddle.net/Gw4Lj/2/

return oFct.apply(sender, args), sender.trigger('contentChange'); 

然而,隨着這種變化,你將不再趕上這是未連接到DOM,因爲它不是該文檔的後代元素上觸發事件,這在我看來是可以的,因爲它沒有關聯到該DOM,它在DOM片段中。

+0

像你說的我不能捕獲事件刪除元素。這就是我要找的。使用$ .event.trigger('contentChange')和$(document).contentChange()觸發事件甚至將元素從DOM中移除。據我瞭解,這是因爲使用$。事件,但然後我不能指定一個元素。我正在尋找$('#test')。contentChange()beeing甚至觸發了元素或孩子被刪除。即使像這樣:return sender.trigger('contentChange'),oFct.apply(sender,args);它不適用於兒童(但適用於自己的元素)。 – 2013-04-10 14:31:42

+0

@roasted但是...爲什麼要通知文檔不會影響文檔的更改?但是,您可以檢測元素是否是文檔的一部分,以及是否不在元素和文檔上觸發事件。 – 2013-04-10 14:34:37

+0

基本上,我想觸發一個特定div的事件,每當一個元素被添加/刪除。如果在$ .event.trigger('contentChange')中使用$(document),但在$ .event.trigger('contentChange')中不使用$('#test'),這似乎可行。我不知道爲什麼? – 2013-04-10 14:45:15