last - que es dom jquery
jQuery: evento de activaciĆ³n cuando se elimina un elemento del DOM (14)
Solución sin usar jQuery UI
( He extraído esta extensión del framework jQuery UI )
Funciona con: empty()
y html()
y 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 );
Con esta solución también puede desvincular el controlador de eventos.
$("YourElemSelector").off("remove");
¡Intentalo! - Ejemplo
$.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>
Estoy intentando averiguar cómo ejecutar algún código js cuando se elimina un elemento de la página:
jQuery(''#some-element'').remove(); // remove some element from the page
/* need to figure out how to independently detect the above happened */
¿Hay un evento adaptado para eso, algo como:
jQuery(''#some-element'').onremoval( function() {
// do post-mortem stuff here
});
Gracias.
Así es como se crea un oyente de jQuery live remove :
$(document).on(''DOMNodeRemoved'', function(e)
{
var $element = $(e.target).find(''.element'');
if ($element.length)
{
// do anything with $element
}
});
O:
$(document).on(''DOMNodeRemoved'', function(e)
{
$(e.target).find(''.element'').each(function()
{
// do anything with $(this)
}
});
El evento "eliminar" de jQuery funciona bien, sin adición. Podría ser más confiable a tiempo usar un simple truco, en lugar de parchear jQuery.
Simplemente modifique o agregue un atributo en el elemento que está a punto de eliminar del DOM. Por lo tanto, puede activar cualquier función de actualización, que simplemente ignorará los elementos en forma de ser destruidos, con el atributo "do_not_count_it".
Supongamos que tenemos una tabla con celdas que corresponden a los precios, y que necesita mostrar solo el último precio: este es el selector que se activa cuando se elimina una celda de precio (tenemos un botón en cada línea de la tabla que hace eso, no se muestra) aquí)
$(''td[validity="count_it"]'').on("remove", function () {
$(this).attr("validity","do_not_count_it");
update_prices();
});
Y aquí hay una función que encuentra el último precio en la tabla, sin tener en cuenta el último, si fue el que se eliminó. De hecho, cuando se desencadena el evento "eliminar" y cuando se llama a esta función, el elemento aún no se ha eliminado.
function update_prices(){
var mytable=$("#pricestable");
var lastpricecell = mytable.find(''td[validity="count_it"]'').last();
}
Al final, la función update_prices () funciona bien, y después de eso, se elimina el elemento DOM.
Esta.
$.each(
$(''#some-element''),
function(i, item){
item.addEventListener(''DOMNodeRemovedFromDocument'',
function(e){ console.log(''I has been removed''); console.log(e);
})
})
Me gusta la respuesta de mtkopone usando eventos especiales de jQuery, pero tenga en cuenta que no funciona a) cuando los elementos se separan en lugar de eliminar o b) cuando algunas bibliotecas antiguas que no son jQuery usan innerHTML para destruir sus elementos
No estoy seguro de que exista un controlador de eventos para esto, por lo que tendría que mantener una copia del DOM y compararlo con el DOM existente en algún tipo de bucle de sondeo, lo que podría ser bastante desagradable. Sin embargo, Firebug hace esto: si inspecciona el HTML y ejecuta algunos cambios de DOM, resalta los cambios en amarillo en la consola de Firebug por un corto tiempo.
Alternativamente, puede crear una función de eliminación ...
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");
No hay un evento incorporado para eliminar elementos, pero puede crear uno mediante el método de eliminación predeterminado de jQuery que se extiende de forma falsa. Tenga en cuenta que se debe llamar a la devolución de llamada antes de eliminarlo para mantener la referencia.
(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();
Nota: algunos problemas con esta respuesta han sido descritos por otros carteles.
- Esto no funcionará cuando el nodo se elimine a través de
html()
replace()
u otros métodos de jQuery - Este evento burbujea
- jQuery UI reemplaza eliminar también
La solución más elegante para este problema parece ser: https://.com/a/10172676/216941
No pude obtener esta respuesta para trabajar con desvinculación (a pesar de la actualización, consulte aquí ), pero pude encontrar una manera de evitarla. La respuesta fue crear un evento especial ''destroy_proxy'' que provocó un evento ''destruido''. Pones a la persona que escucha el evento en ''destruido_proxy'' y ''destruido'', luego, cuando quieres desenlazar, simplemente desenlaza el evento ''destruido'':
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++;
});
Aquí hay un fiddle
Para aquellos que usan jQuery UI:
La interfaz de usuario de jQuery ha reemplazado algunos de los métodos de jQuery para implementar un evento de remove
que se maneja no solo cuando se elimina explícitamente el elemento dado, sino también si el elemento se elimina del DOM mediante algún método de autolimpieza de jQuery (por ejemplo, replace
, html
, etc.). Básicamente, esto le permite poner un gancho en los mismos eventos que se activan cuando jQuery está "limpiando" los eventos y datos asociados con un elemento DOM.
John Resig ha indicado que está abierto a la idea de implementar este evento en una versión futura de jQuery core, pero no estoy seguro de cuál es la situación actual.
Puede vincularse al evento DOMNodeRemoved (parte de la especificación DOM3 del nivel 3 de DOM).
Funciona en IE9, últimas versiones de Firefox y Chrome.
Ejemplo:
$(document).bind("DOMNodeRemoved", function(e)
{
alert("Removed: " + e.target.nodeName);
});
También puede obtener una notificación cuando se insertan elementos vinculando a DOMNodeInserted
Puedes usar los eventos especiales de jQuery para esto.
En toda simplicidad,
Preparar:
(function($){
$.event.special.destroyed = {
remove: function(o) {
if (o.handler) {
o.handler()
}
}
}
})(jQuery)
Uso:
$(''.thing'').bind(''destroyed'', function() {
// do stuff
})
Anexo a los comentarios de Pierre y DesignerGuy:
Para no hacer que se active la devolución de llamada al llamar a $(''.thing'').off(''destroyed'')
, cambie la condición if a: if (o.handler && o.type !== ''destroyed'') { ... }
Recién comprobado, ya está incorporado en la versión actual de JQuery:
jQuery - v1.9.1
jQuery UI - v1.10.2
$("#myDiv").on("remove", function () {
alert("Element was removed");
})
Importante : Esta es la funcionalidad del script de Jquery UI (no de JQuery), por lo que debe cargar ambos scripts (jquery y jquery-ui) para que funcione. Aquí está el ejemplo: http://jsfiddle.net/72RTz/
haciendo referencia a la respuesta de @David:
Cuando quieras hacerlo con otra función, ej. html () como en mi caso, no olvide agregar return en la nueva función:
(function() {
var ev = new $.Event(''html''),
orig = $.fn.html;
$.fn.html = function() {
$(this).trigger(ev);
return orig.apply(this, arguments);
}
})();
.remove()
no es la mejor manera de manejar esto, ya que hay muchas formas de eliminar elementos de la página (por ejemplo, utilizando .html()
, .replace()
, etc.).
Para evitar diversos riesgos de pérdida de memoria, jQuery intentará llamar a la función jQuery.cleanData()
para cada elemento eliminado, independientemente del método utilizado para eliminarlo.
Ver esta respuesta para más detalles: fugas de memoria javascript
Por lo tanto, para obtener los mejores resultados, debe enganchar la función cleanData
, que es exactamente lo que hace el complemento jquery.event.destroyed :
http://v3.javascriptmvc.com/jquery/dist/jquery.event.destroyed.js