Direct vs. Delegated - jQuery .on()

前端 未结 5 1491
鱼传尺愫
鱼传尺愫 2020-11-21 05:11

I am trying to understand this particular difference between the direct and delegated event handlers using the jQuery .on() method. Specifically, the last

相关标签:
5条回答
  • 2020-11-21 05:19

    The explanation of N3dst4 is perfect. Based on this, we can assume that all child elements are inside body, therefore we need use only this:

    $('body').on('click', '.element', function(){
        alert('It works!')
    });
    

    It works with direct or delegate event.

    0 讨论(0)
  • 2020-11-21 05:20

    The first way, $("div#target span.green").on(), binds a click handler directly to the span(s) that match the selector at the moment that code is executed. This means if other spans are added later (or have their class changed to match) they have missed out and will not have a click handler. It also means if you later remove the "green" class from one of the spans its click handler will continue to run - jQuery doesn't keep track of how the handler was assigned and check to see if the selector still matches.

    The second way, $("div#target").on(), binds a click handler to the div(s) that match (again, this is against those that match at that moment), but when a click occurs somewhere in the div the handler function will only be run if the click occurred not just in the div but in a child element matching the selector in the second parameter to .on(), "span.green". Done this way it doesn't matter when those child spans were created, clicking upon them will still run the handler.

    So for a page that isn't dynamically adding or changing its contents you won't notice a difference between the two methods. If you are dynamically adding extra child elements the second syntax means you don't have to worry about assigning click handlers to them because you've already done it once on the parent.

    0 讨论(0)
  • 2020-11-21 05:26

    I wro te a post with a comparison of direct events and delegated. I compare pure js but it has the same meaning for jquery which only encapsulate it.

    Conclusion is that delegated event handling is for dynamic DOM structure where binded elements can be created while user interact with page ( no need again bindings ), and direct event handling is for static DOM elements, when we know that structure will not change.

    For more information and full comparison - http://maciejsikora.com/standard-events-vs-event-delegation/

    Using always delegated handlers, which I see is current very trendy is not right way, many programmers use it because "it should be used", but truth is that direct event handlers are better for some situation and the choice which method use should be supported by knowledge of differences.

    0 讨论(0)
  • 2020-11-21 05:30

    Tangential to the OP, but the concept that helped me unravel confusion with this feature is that the bound elements must be parents of the selected elements.

    • Bound refers to what is left of the .on.
    • Selected refers to the 2nd argument of .on().

    Delegation does not work like .find(), selecting a subset of the bound elements. The selector only applies to strict child elements.

    $("span.green").on("click", ...
    

    is very different from

    $("span").on("click", ".green", ...
    

    In particular, to gain the advantages @N3dst4 hints at with "elements that are created in future" the bound element must be a permanent parent. Then the selected children can come and go.

    EDIT

    Checklist of why delegated .on doesn't work

    Tricky reasons why $('.bound').on('event', '.selected', some_function) may not work:

    1. Bound element is not permanent. It was created after calling .on()
    2. Selected element is not a proper child of a bound element. It's the same element.
    3. Selected element prevented bubbling of an event to the bound element by calling .stopPropagation().

    (Omitting less tricky reasons, such as a misspelled selector.)

    0 讨论(0)
  • 2020-11-21 05:35

    Case 1 (direct):

    $("div#target span.green").on("click", function() {...});
    

    == Hey! I want every span.green inside div#target to listen up: when you get clicked on, do X.

    Case 2 (delegated):

    $("div#target").on("click", "span.green", function() {...});
    

    == Hey, div#target! When any of your child elements which are "span.green" get clicked, do X with them.

    In other words...

    In case 1, each of those spans has been individually given instructions. If new spans get created, they won't have heard the instruction and won't respond to clicks. Each span is directly responsible for its own events.

    In case 2, only the container has been given the instruction; it is responsible for noticing clicks on behalf of its child elements. The work of catching events has been delegated. This also means that the instruction will be carried out for child elements that are created in future.

    0 讨论(0)
提交回复
热议问题