programing

jQuery - 요소가 DOM에서 제거될 때 이벤트를 트리거합니다.

skycolor 2023. 8. 25. 23:27
반응형

jQuery - 요소가 DOM에서 제거될 때 이벤트를 트리거합니다.

페이지에서 요소를 제거할 때 js 코드를 실행하는 방법을 찾고 있습니다.

jQuery('#some-element').remove(); // remove some element from the page
/* need to figure out how to independently detect the above happened */

이에 맞는 맞춤형 이벤트가 있습니까?

jQuery('#some-element').onremoval( function() {
    // do post-mortem stuff here
});

이에 대해 jQuery 특별 이벤트를 사용할 수 있습니다.

간단히 말해서,

설정:

(function($){
  $.event.special.destroyed = {
    remove: function(o) {
      if (o.handler) {
        o.handler()
      }
    }
  }
})(jQuery)

용도:

$('.thing').bind('destroyed', function() {
  // do stuff
})

Pierre와 Designer Guy의 의견에 답하기 위한 부록:

전화를 걸 때 콜백 기능이 없는 경우$('.thing').off('destroyed')if 조건을 다음으로 변경합니다.if (o.handler && o.type !== 'destroyed') { ... }

방금 확인했습니다. JQuery의 현재 버전에는 이미 기본 제공됩니다.

jQuery - v1.9.1

jQuery UI - v1.10.2

$("#myDiv").on("remove", function () {
    alert("Element was removed");
})

중요:이것은 JQuery UI 스크립트(JQuery가 아님)의 기능이므로 작동하려면 두 스크립트(jquery와 jquery-ui)를 모두 로드해야 합니다.예: http://jsfiddle.net/72RTz/

DOM 노드 제거 이벤트(DOM 레벨 3 WC3 사양의 일부)에 바인딩할 수 있습니다.

Firefox 및 Chrome의 최신 릴리스인 IE9에서 작동합니다.

예:

$(document).bind("DOMNodeRemoved", function(e)
{
    alert("Removed: " + e.target.nodeName);
});

또한 요소가 삽입될 때 다음 항목에 바인딩하여 알림을 받을 수 있습니다.DOMNodeInserted

요소 제거를 위한 내장 이벤트는 없지만 jQuery의 기본 제거 방법을 가짜로 확장하여 생성할 수 있습니다.참조를 유지하기 위해 콜백을 실제로 제거하기 전에 콜백을 호출해야 합니다.

(function() {
    var ev = new $.Event('remove'),
        orig = $.fn.remove;
    $.fn.remove = function() {
        $(this).trigger(ev);
        return orig.apply(this, arguments);
    }
})();

$('#some-element').bind('remove', function() {
    console.log('removed!');
    // do pre-mortem stuff here
    // 'this' is still a reference to the element, before removing it
});

// some other js code here [...]

$('#some-element').remove();

참고: 이 답변과 관련된 몇 가지 문제는 다른 포스터를 통해 요약되었습니다.

  1. 노드가 다음을 통해 제거되면 작동하지 않습니다.html() replace()또는 다른 jQuery 메서드
  2. 이 이벤트는 거품이 일었습니다.
  3. jQuery UI는 제거도 재정의합니다.

이 문제에 대한 가장 우아한 해결책은 https://stackoverflow.com/a/10172676/216941 인 것 같습니다.

페이지에서 요소를 제거하는 방법은 여러 가지가 있으므로(예: , 등을 사용하여) 후킹은 이 문제를 처리하는 최선의 방법이 아닙니다.

다양한 메모리 누수 위험을 방지하기 위해 jQuery는 제거에 사용된 방법에 관계없이 제거된 각 요소에 대해 함수 호출을 시도합니다.

자세한 내용은 다음 답변을 참조하십시오: Javascript 메모리 누수

따라서 최상의 결과를 얻으려면 다음을 연결해야 합니다.cleanData함수.jquery.event.vmx 플러그인이 수행하는 작업은 다음과 같습니다.

http://v3.javascriptmvc.com/jquery/dist/jquery.event.destroyed.js

jQuery UI를 사용하는 사용자의 경우:

jQuery UI가 일부 jQuery 메서드를 재정의하여remove요소를 해당 청소 방법 JQuery)에 될 때 입니다.replace,html를 ".이를 통해 기본적으로 JQuery가 DOM 요소와 관련된 이벤트 및 데이터를 "정리"할 때 발생하는 동일한 이벤트에 훅을 넣을 수 있습니다.

John Resig는 jQuery core의 미래 버전에서 이 이벤트를 구현하는 것에 대해 개방적이라고 밝혔지만, 현재 상황은 잘 모르겠습니다.

jQuery만 필요합니다(jQuery UI 필요 없음)

(jQuery UI 프레임워크에서 이 확장자를 추출했습니다.)

작업대상:empty()그리고.html()그리고.remove()

$.cleanData = ( function( orig ) {
    return function( elems ) {
        var events, elem, i;
        for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
            try {

                // Only trigger remove when necessary to save time
                events = $._data( elem, "events" );
                if ( events && events.remove ) {
                    $( elem ).triggerHandler( "remove" );
                }

            // Http://bugs.jquery.com/ticket/8235
            } catch ( e ) {}
        }
        orig( elems );
    };
} )( $.cleanData );

이 솔루션을 사용하면 이벤트 처리기의 바인딩을 해제할 수도 있습니다.

$("YourElemSelector").off("remove");

사용해 보세요! - 예

$.cleanData = (function(orig) {
  return function(elems) {
    var events, elem, i;
    for (i = 0;
      (elem = elems[i]) != null; i++) {
      try {

        // Only trigger remove when necessary to save time
        events = $._data(elem, "events");
        if (events && events.remove) {
          $(elem).triggerHandler("remove");
        }

        // Http://bugs.jquery.com/ticket/8235
      } catch (e) {}
    }
    orig(elems);
  };
})($.cleanData);


$("#DivToBeRemoved").on("remove", function() {
  console.log("div was removed event fired");
});

$("p").on("remove", function() {
  console.log("p was removed event fired");
});

$("span").on("remove", function() {
  console.log("span was removed event fired");
});

// $("span").off("remove");

$("#DivToBeRemoved").on("click", function() {
  console.log("Div was clicked");
});

function RemoveDiv() {
  //       $("#DivToBeRemoved").parent().html("");    
  $("#DivToBeRemoved").remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>OnRemove event handler attached to elements `div`, `p` and `span`.</h3>
<div class="container">
  <br>
  <button onclick="RemoveDiv();">Click here to remove div below</button>
  <div id="DivToBeRemoved">
    DIV TO BE REMOVED 
    contains 1 p element 
    which in turn contains a span element
    <p>i am p (within div)
      <br><br><span>i am span (within div)</span></p>
  </div>
</div>

추가 데모 - jsBin

구속력이 없는 상태에서 이 답변을 받을 수는 없었지만(여기 업데이트 내용 참조) 해결 방법을 찾을 수 있었습니다.정답은 'destroy_proxy' 특수 이벤트를 생성하여 'destroy' 이벤트를 트리거하는 것이었습니다.이벤트 수신기를 'destroy_proxy'와 'destroy'로 모두 설정한 다음 바인딩을 해제하려면 'destroy' 이벤트의 바인딩을 해제합니다.

var count = 1;
(function ($) {
    $.event.special.destroyed_proxy = {
        remove: function (o) {
            $(this).trigger('destroyed');
        }
    }
})(jQuery)

$('.remove').on('click', function () {
    $(this).parent().remove();
});

$('li').on('destroyed_proxy destroyed', function () {
    console.log('Element removed');
    if (count > 2) {
        $('li').off('destroyed');
        console.log('unbinded');
    }
    count++;
});

여기 바이올린이 있습니다.

나는 jQuery 특수 이벤트를 사용하는 mtkopone의 답변을 좋아하지만 a) 요소가 제거되지 않고 분리된 경우 또는 b) 일부 오래된 비jquery 라이브러리가 내부를 사용하는 경우에는 작동하지 않습니다.HTML을 사용하여 요소를 파괴합니다.

이에 대한 이벤트 핸들이 있는지 확신할 수 없기 때문에 DOM의 복사본을 보관하고 어떤 종류의 폴링 루프에서 기존 DOM과 비교해야 합니다. 이는 상당히 불쾌할 수 있습니다.그러나 Firebug는 HTML을 검사하고 일부 DOM 변경을 실행하면 Firebug 콘솔에서 노란색으로 변경된 내용을 짧은 시간 동안 강조 표시합니다.

또는 제거 기능을 만들 수 있습니다...

var removeElements = function(selector) {
    var elems = jQuery(selector);

    // Your code to notify the removal of the element here...
    alert(elems.length + " elements removed");

    jQuery(selector).remove();
};

// Sample usage
removeElements("#some-element");
removeElements("p");
removeElements(".myclass");

이것.

$.each(
  $('#some-element'), 
        function(i, item){
            item.addEventListener('DOMNodeRemovedFromDocument',
                function(e){ console.log('I has been removed'); console.log(e);
                })
         })

다음은 jQuery Live Remove 수신기를 만드는 방법입니다.

$(document).on('DOMNodeRemoved', function(e)
{
  var $element = $(e.target).find('.element');
  if ($element.length)
  {
    // do anything with $element
  }
});

또는:

$(document).on('DOMNodeRemoved', function(e)
{
  $(e.target).find('.element').each(function()
  {
    // do anything with $(this)
  }
});

jQuery의 "제거" 이벤트는 추가 없이 정상적으로 작동합니다.jQuery에 패치를 적용하는 대신 간단한 트릭을 사용하는 것이 나중에 더 신뢰할 수 있습니다.

DOM에서 제거하려는 요소에서 속성을 수정하거나 추가하기만 하면 됩니다.따라서 "do_not_count_it" 속성을 사용하여 삭제할 요소를 무시하는 모든 업데이트 함수를 트리거할 수 있습니다.

가격에 해당하는 셀이 있는 테이블이 있고 마지막 가격만 표시하면 된다고 가정합니다.가격 셀이 삭제될 때 트리거할 선택기입니다(표의 각 줄에는 여기에 표시되지 않은 버튼이 있습니다).

$('td[validity="count_it"]').on("remove", function () {
    $(this).attr("validity","do_not_count_it");
    update_prices();
});

그리고 여기 마지막 가격을 찾는 함수가 있습니다. 마지막 가격을 고려하지 않고, 제거된 가격을 계산합니다.실제로 "제거" 이벤트가 트리거되고 이 함수가 호출되면 요소가 아직 제거되지 않습니다.

function update_prices(){
      var mytable=$("#pricestable");
      var lastpricecell = mytable.find('td[validity="count_it"]').last();
}

결국 update_price() 함수는 정상적으로 작동하고, 그 후 DOM 요소는 제거됩니다.

DOM Node Removed를 사용할 수도 있습니다.

$("#youridwhichremoved").on("DOMNodeRemoved", function () {
// do stuff
})

@David 답변 참조:

당신이 다른 함수로 soo를 하고 싶을 때, 예를 들어 나의 경우처럼 html(), 새 함수에 리턴을 추가하는 것을 잊지 마십시오.

(function() {
    var ev = new $.Event('html'),
        orig = $.fn.html;
    $.fn.html = function() {
        $(this).trigger(ev);
        return orig.apply(this, arguments);
    }
})();

기본값을 방지해야 할 경우를 대비하여 Adam의 답변에 대한 확장자로, 다음과 같은 해결 방법이 있습니다.

$(document).on('DOMNodeRemoved', function(e){
        if($(e.target).hasClass('my-elm') && !e.target.hasAttribute('is-clone')){
            let clone = $(e.target).clone();
            $(clone).attr('is-clone', ''); //allows the clone to be removed without triggering the function again

            //you can do stuff to clone here (ex: add a fade animation)

            $(clone).insertAfter(e.target);
            setTimeout(() => {
                //optional remove clone after 1 second
                $(clone).remove();
            }, 1000);
        }
    });

언급URL : https://stackoverflow.com/questions/2200494/jquery-trigger-event-when-an-element-is-removed-from-the-dom

반응형