Table: RailsNotes
User: dreamable
Created at: 2021-03-02 11:25:21 UTC
Updated at: 2021-03-02 22:36:31 UTC
Reference:(Table ID 3, Record ID 28)

标题 :
Make JQuery binding click events work for dynamically generated elements.
笔记 :

I have bind a click events to <a> like:

$(document).on("turbolinks:load", function() {
  $('a.click-toggle-id').click(function (e) {
    console.log("click-toggle-id clicked")
    // prevent the default click action
    e.preventDefault();
    let tid = $(this).attr('toggle-id');
    console.log(tid)
    $("#"+tid).toggle();
  });
});

This works well for static elements, but not for dynamically generated elements, e.g. elements added by js.erb files.

I found this guide. The problem is I should use on instead of click and use the top-level container document.

$(document).on("turbolinks:load", function() {
  // NOT WORK $('a').on('click','.click-toggle-id',function (e) {
  $(document).on('click','a.click-toggle-id',function (e) {
    console.log("click-toggle-id clicked")
    // prevent the default click action
    e.preventDefault();
    let tid = $(this).attr('toggle-id');
    console.log(tid)
    $("#"+tid).toggle();
  });
});

More details

$( selector ).click( function() )
$( selector ).on( 'click', function() )

The problem with this method is that your event handlers will need to be attached each time your DOM is modified. JS updated your DOM, but the turbolinks:load not fired.

Delegated event handling:

$( document ).on( 'click', '.click_link', function() )

When using jQuery on() with delegate events, the event is bound to the top level element, but when it runs, the children of the element are traversed looking for matches for the selector. This has the added benefit of making your code idempotent, and further, can be used in instances where you are modifying your DOM structure on the fly and have new elements created which should handle events.

The only downside (that I know of) to this approach is that event propagation may happen more slowly.This means if you stop event propagation (using event.preventDefault() or event.stopPropagation()), it may not occur in time to prevent all the events from firing that you want. This doesn't cause problems for links to '#' which are handled with event.preventDefault(), but it may cause issues in other cases where you have multiple event handlers on one element.

Tag: