我正试图弄清楚当从页面中删除元素时如何执行一些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
});
感谢。
答案 0 :(得分:194)
您可以使用 jQuery特殊活动。
简单来说,
设定:
(function($){
$.event.special.destroyed = {
remove: function(o) {
if (o.handler) {
o.handler()
}
}
}
})(jQuery)
用法:
$('.thing').bind('destroyed', function() {
// do stuff
})
回答Pierre和DesignerGuy评论的补遗:
要在调用$('.thing').off('destroyed')
时没有回拨,请将if条件更改为:if (o.handler && o.type !== 'destroyed') { ... }
答案 1 :(得分:112)
刚刚检查过,它已经内置在当前版本的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/
答案 2 :(得分:46)
您可以绑定到DOMNodeRemoved事件(DOM Level 3 WC3规范的一部分)。
适用于IE9,最新版本的Firefox和Chrome。
示例:
$(document).bind("DOMNodeRemoved", function(e)
{
alert("Removed: " + e.target.nodeName);
});
通过绑定到DOMNodeInserted
答案 3 :(得分:37)
没有用于删除元素的内置事件,但您可以通过伪扩展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();
注意:其他海报已经概述了这个答案的一些问题。
html()
replace()
或其他jQuery方法删除节点时,这不起作用这个问题最优雅的解决方案似乎是:https://stackoverflow.com/a/10172676/216941
答案 4 :(得分:32)
挂钩.remove()
不是处理此问题的最佳方式,因为有很多方法可以从页面中删除元素(例如,使用.html()
,.replace()
等)。
为了防止各种内存泄漏危险,内部jQuery会尝试为每个被删除的元素调用 jQuery.cleanData()
函数,而不管用于删除它的方法。
有关详细信息,请参阅此答案:javascript memory leaks
因此,为了获得最佳效果,您应该挂钩cleanData
函数,这正是jquery.event.destroyed插件的作用:
http://v3.javascriptmvc.com/jquery/dist/jquery.event.destroyed.js
答案 5 :(得分:7)
对于那些使用jQuery UI的人:
jQuery UI已经覆盖了一些jQuery方法来实现一个remove
事件,该事件不仅在您显式删除给定元素时被处理,而且还会通过任何自清理jQuery从DOM中删除该元素方法(例如replace
,html
等)。这基本上允许你在jQuery“清理”与DOM元素相关的事件和数据时触发相同的事件。
John Resig has indicated他对在jQuery核心的未来版本中实现此事件的想法持开放态度,但我不确定它目前的位置。
答案 6 :(得分:4)
我无法让this answer使用解除绑定(尽管更新see here),但能够找到解决方法。答案是创建一个' destroy_proxy'引发“被摧毁”的特殊事件。事件。您将事件监听器放在' destroyed_proxy'然后当你想要解开时,你就解开了被摧毁的'事件:
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++;
});
这是fiddle
答案 7 :(得分:4)
(我从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>
&#13;
答案 8 :(得分:3)
我喜欢mtkopone使用jQuery特殊事件的答案,但请注意它不起作用a)当元素被分离而不是删除时b)当一些旧的非jquery库使用innerHTML来破坏你的元素时
答案 9 :(得分:1)
我不确定是否有一个事件句柄,因此您必须保留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");
答案 10 :(得分:1)
这是如何创建jQuery 实时删除侦听器:
$(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)
}
});
答案 11 :(得分:1)
从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_prices()函数可以正常工作,然后删除DOM元素。
答案 12 :(得分:0)
引用@David回答:
当您想要使用其他功能时,例如。 html()就像我的情况一样,不要忘记在新函数中添加return:
(function() {
var ev = new $.Event('html'),
orig = $.fn.html;
$.fn.html = function() {
$(this).trigger(ev);
return orig.apply(this, arguments);
}
})();
答案 13 :(得分:0)
此。
$.each(
$('#some-element'),
function(i, item){
item.addEventListener('DOMNodeRemovedFromDocument',
function(e){ console.log('I has been removed'); console.log(e);
})
})
答案 14 :(得分:0)
Adam's的扩展名,如果您需要防止默认设置,可以通过以下方法解决:
$(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);
}
});
答案 15 :(得分:0)
我们还可以使用DOMNodeRemoved:
$("#youridwhichremoved").on("DOMNodeRemoved", function () {
// do stuff
})