2012-02-14 11 views
6

Aquí hay un ejemplo condensado.Al hacer un .replaceWith() en jQuery no se conservan los enlaces de eventos

Tenga en cuenta que la clase .chat-reply tiene asociado un controlador de evento click.

El HTML (botón de respuesta):

<div class="container"> 
    <a href="#" class="btn small chat-reply">Reply</a> 
</div> 

Esta función jQuery se llama cuando alguien hace clic en otro botón que envía un mensaje al servidor que se guardan en la base de datos. Esto se hace a través de ajax y se realiza con éxito. En el éxito .ajax mencionada()() devolución de llamada esta función se llama:

$.ajax({ 
     type  : 'GET', 
     url  : '/some_controller/some_method', 
     success : function(data) { 

     $('.container').replaceWith(data); 
    } 
}); 

El 'datos' en la devolución de llamada éxito anterior reemplazará toda la div .container incluyendo el botón .chat-respuesta del niño. Después de esto replaceWith(), el evento click ya no está vinculado al botón.

Lógicamente, estoy intentando que el usuario final publique un mensaje en una línea de tiempo, luego haga que aparezca ese mensaje en la línea de tiempo sin que necesite actualizar la pantalla.

Respuesta

1

decidimos por una solución más bien no tan elegante gracias en parte a este post: Events not registering after replaceWith

creé una función llamada wireUpChatReply() que se une un evento de clic al botón .chat-respuesta.

Luego, después de replaceWith(), realizo una llamada a wireUpChatReply() para volver a vincular los eventos.Hago esta misma llamada a wireUpChatReply en document.ready.

No es bonito, pero funciona.

3

Grab jQuery 1.7 que utiliza ahora 'on' para unirse: http://blog.jquery.com/2011/09/28/jquery-1-7-beta-1-released/

O si < 1.7 uso 'en vivo' en lugar de 'bind', ya que buscará cambios DOM y volver a aplicar los eventos de contenido modificado . Si no puede volver a aplicar el evento en su devolución de llamada.

Vieja aplicación de reemplazo para vincular con los controladores de eventos de tipo en vivo después de los cambios DOM.

este $ (selector) .live (eventos, fn)

convierte este $ (document) .en (eventos, selector, fn)

o en el código

este

$(".container a.chat-reply").live("click", function(){ 
// do it live! 
}); 

Se convierte esto en 1.7

$(".container").on("click", "a.chat-reply", function(event){ 
// do it live! 
}); 

Con varias opciones para seleccionar el objeto que desea.

+0

Su ejemplo de código es un poco confuso para mí. Si no te importa aclarar un poco, sería genial. – generalopinion

+0

Sry el bloque estaba apuntando desde el antiguo "directo" al "encendido", pero el ejemplo de Vigrond es cómo haces un "encendido". Sería casi mejor adjuntar el evento después de que se recibió el html en su devolución de llamada. –

2

En el controlador de clic, utilice .on() como un delegado en lugar

$("div.container").on("click", "a.chat-reply", function(even){ 
    //click handler here 
}); 

el evento será 'burbuja' hasta contenedor, y si coincide con a.chat-repetición se activará.

+0

Sin embargo, el "burbujeo" funcionó una vez que hago un replaceWith(), esos enlaces de eventos se han ido, aún. – generalopinion

+0

por supuesto. my bad, replaceWith reemplazará el elemento completo. ¿Es posible para ti hacer .html (contenido) en su lugar? Eso reemplazará su contenido, no el elemento .container. De lo contrario, tendrá que comenzar a buscar a los antepasados ​​de .container para adjuntar el controlador de eventos .on. – Vigrond

+0

Ewww. Eso puede ponerse desagradable. Encontré otra publicación que sugería tener una función que "conecta por cable" el enlace del evento. Luego llamándolo de nuevo DESPUÉS de replaceWith(). No es bonito, pero es posible que no tenga muchas opciones. – generalopinion

0

Las dos respuestas con respecto a los eventos en vivo no solucionan el problema, porque el contenedor en sí se reemplaza y el enlace del evento se ha ido.

En lugar de volver a vincular los eventos, en cuyo caso se necesita saber los eventos ya consolidados, se puede hacer lo siguiente:

$(".container").parent().on("click", ".container a.chat-reply", function(){ 
    // do something 
}); 

o, si hay varios recipientes:

$(document.body).on("click", ".container a.chat-reply", function(){ 
    // do something 
}); 
Cuestiones relacionadas