2

汚いタイトルで申し訳ありませんが、これをどのように表現すればよいかわかりません。要素に関連付けられているロジックがあり、要素が削除されるたびにデストラクタのような関数が呼び出されるようにしたいと考えています。このトリガーとして DOMNodeRemoved を使用してみましたが、次のように正しく機能しません。

  • DOMNodeRemoved は、要素自体ではなく、要素の親に対してのみ発生します。
  • 変な順番で発火するようなので、ちゃんと処分するためにイベントをちゃんと受け取れないことがあります。

コード: (またはフィドル)

<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についてはまったく気にしません。

4

1 に答える 1

4

jQuery UI には、削除イベントをトリガーする 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 );
};

.empty().remove()、などの jQuery メソッドを使用して要素を削除する限り、 remove イベントを使用できるようになりました.html()http://jsfiddle.net/2dwbk/

もちろん、jQuery UI が含まれている場合は、上記のコードはまったく必要なく、単に remove イベントにバインドするだけです。

于 2012-12-17T23:00:25.113 に答える