2012-12-17 27 views
2

對於錯誤的標題,我表示歉意,但我不知道如何將此內容加以說明。我有附加到元素的邏輯,並且希望每當刪除元素時都會調用類析構函數。我已經使用DOMNodeRemoved因爲這觸發嘗試,然而,這不能正常工作,如:JQuery - 檢測自己/垃圾收集上的DOMNodeRemoved

  • DOMNodeRemoved只解僱元素的父母,而不是元素本身。
  • 它似乎以特殊的順序開火,所以有時候我沒有正確地處理事件。

代碼:(或fiddle

<widget id="widget"> 
    <div>Widget 1</div> 
    <widget id="widget2"> 
     <div>Widget 2</div> 
    </widget> 
</widget> 

<input type="button" value="remove widget" />​ 

使用Javascript:

var Widget = function(element) { 
    this.initialize(this.element = element); 
}; 

Widget.prototype = { 
    initialize: function() { 

     // does not work for the elements at all 
     $(this.element).on('DOMNodeRemoved', this.onRemoved.bind(this)); 

     // works, but is not optimal, fired whenever any node is removed. 
     // DOMNodeRemovedFromDocument doesn't fire for me in latest Chrome 
     $(this.element).parent().on('DOMNodeRemoved', this.onRemoved.bind(this)); 

     // here is code that adds to a manager 
     console.log('ADD TO SOME MANAGER', $(this.element).attr('id')); 
    }, 

    /** 
    * @private 
    * Callback for when the element is removed from the DOM 
    */ 
    onRemoved: function(ev) { 

     if (ev.target !== this.element) { 
      return; 
     } 

     this.dispose(); 
    }, 

    /** 
    * My callback for disposal/destructor 
    */ 
    dispose: function() { 

     // here is code that removes from a manager 
     console.log('REMOVE FROM SOME MANAGER', $(this.element).attr('id')); 
    } 
}; 

$(document).ready(function() { 

    $(this.body).find('widget').each(function(index, element) { 

     // store widget 
     $(element).data('widget', new Widget(element)); 

    }); 

    $(this.body).find('input[type=button]').click(function() { 
     $('#widget').remove(); 
    }); 

});​ 

上述代碼應輸出:

// ADD TO SOME MANAGER widget 
// ADD TO SOME MANAGER widget2 
// REMOVE FROM SOME MANAGER widget2 (this should be here but isn't) 
// REMOVE FROM SOME MANAGER widget 

是否有某種標準的是,用於將邏輯綁定到jQuery中的元素?或者我將不得不做一些猴修補重寫「刪除」的方法(不是首選,因爲一些元素可能會被刪除不使用jquery的方法)

編輯:我不在乎所有關於IE瀏覽器。

+0

只要讓jQuery爲你做這些工作:看看'.remove()'和'.detach'之間的區別! – Bergi

+0

errrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr ???????????????這與釋放元素移除的回調沒有關係? – ansiart

+0

啊,你需要明確地啓動'removeFromManager'函數,我以爲你只關心那個'data'垃圾。如果是這樣的話,我會建議公開一個'Widget.destroy'方法,它從DOM和那個管理器中移除這個小部件,而不是掛在不可靠的突變事件上,並試圖用DOM'remove'來解僱它們。 – Bergi

回答

4

jQuery UI對觸發remove事件的cleanData內部jQuery方法有一個內置的改變。如果你在你的代碼中實現它,你可以用它來解決你的問題。

var _cleanData = $.cleanData; 
$.cleanData = function(elems) { 
    for (var i = 0, elem; (elem = elems[i]) != null; i++) { 
     try { 
      $(elem).triggerHandler("remove"); 
     // http://bugs.jquery.com/ticket/8235 
     } catch(e) {} 
    } 
    _cleanData(elems); 
}; 

現在可以只要元件使用一個jQuery方法如.empty().remove(),或.html()除去使用remove事件。 http://jsfiddle.net/2dwbk/

當然,如果你有jQuery UI包含,你根本不需要上面的代碼,只需綁定到remove事件。

+0

謝謝,會給它一個旋轉。 – ansiart

+0

奇妙地工作,謝謝。 – ansiart