When .replaceWith () is executed in jQuery event bindings are not saved

Here is an example.

Keep in mind that the .chat-reply class has a click event handler associated with it.

HTML (response button):

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

This jQuery function is called when someone clicks the other button, which sends a message to the server for storage in the database. This is done using ajax and succeeds. In the aforementioned .ajax () success () callback, this function is called:

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

The "data" in the previous callback will be replaced by the whole .container div, including the .chat-reply child button. After this replaceWith (), the click event is no longer attached to the button.

Logically, I am trying to have the end user post a message on the timeline, then display this message on the timeline without to refresh the screen.

+6
source share
4 answers

Solved by a rather not-so-elegant solution, thanks in part to this post: Events that are not logged after replacementWith

I created a function called wireUpChatReply () that binds the click event to the .chat-reply button.

Then, after replacingWith (), I make a call to wireUpChatReply () to reorder the events. I am making the same call to wireUpChatReply on document.ready.

This is not very, but it works.

+1
source

Grab jquery 1.7 which now uses 'on' for binding: http://blog.jquery.com/2011/09/28/jquery-1-7-beta-1-released/

Or, if <1.7 use 'live' instead of 'bind', as it will look for DOM changes and reapply the events of the changed content. If not, you can reapply the event in your callback.

Old replacement api for binding with real-time event handlers after DOM changes.

$ (selector) .live (events, fn)

becomes $ (document) .on (events, selector, fn)

Or in code

it

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

It becomes in 1.7

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

With various options for selecting the desired object.

+3
source

In the click handler, use .on () instead of the delegate

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

the event will bubble up to the container, and if it matches a.chat-replay, it will fire.

+2
source

Two answers related to live events do not fix the problem, because the container itself is replaced and the event binding is gone.

Instead of reordering events, in this case you need to know the events already connected, you can do the following:

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

or if there are several containers:

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

Source: https://habr.com/ru/post/908392/


All Articles