0

On Jquery 'delegation', I am not able to understand this delegating events, Any help on this?

what if i use,

case 1

$( "table td" ).on( "click", function() {
  $( this ).toggleClass( "chosen" );
});

case 2

$( "table" ).delegate( "td", "click", function() {
  $( this ).toggleClass( "chosen" );
});

Both will do the same job. If so, what is the main difference?[I am not able to understand]. Is anything related to 'Event Bubbling'? Please

User123
  • 453
  • 2
  • 6
  • 17
  • 1
    first one - there is no event delegation - to use delegation `$( "table" ).on( "click", "td", function() {});` – Arun P Johny May 07 '15 at 13:52
  • @ArunPJohny, Actually, I am lacking in understanding 'delegation'. You are not making sense that i try to understand. Could you please read my question and answer? – User123 May 07 '15 at 13:56
  • http://jsfiddle.net/arunpjohny/8qukx12t/1/ - Look at this example - The elements added after the handler is added is not getting executed if delegation was not used – Arun P Johny May 07 '15 at 13:58
  • @ArunPJohny, I am not able to understand anything, As far as I understand, all 'td' are working when I click on the table. I could not see the difference and Importance on delegation. – User123 May 07 '15 at 14:09
  • @User123 Only the first element gets the first listener that sets the `chosen` class. All elements (created later) get the other two listeners that set `chosen2` and `chosen3`, because those listeners are set via delegation. – apsillers May 07 '15 at 14:12
  • possible duplicate of [Direct vs. Delegated - jQuery .on()](http://stackoverflow.com/questions/8110934/direct-vs-delegated-jquery-on) – isherwood May 07 '15 at 14:24

2 Answers2

0

Case 1 binds the onclick handler for all <td> nodes that are already present in DOM at the moment you bind that handler. If you decide to add another <td> dynamically to your table, your event handler won't be called for this new <td>.

Case 2, which in fact should look like this (since As of jQuery 1.7, .delegate() has been superseded by the .on() method):

$( "table" ).on( "click", "td", function() {
  ...
});

is there to overcome the issue described above. I.e. your event handler will be called even for the <td> nodes added dynamically after the moment you bind that handler.

More info: https://learn.jquery.com/events/event-delegation/

dekkard
  • 6,121
  • 1
  • 16
  • 26
0

The practical difference is that delegate (and three-argument on) can cause listeners to apply to elements that don't exist yet.

$( "table td" ).on( "click", ...) attaches a listener to every element that matches the table td selector that exists at the time the call is made. If a td is added to the page after this call, it won't have a listener attached to it.

$( "table" ).delegate( "td", "click", ...) attaches a listener to every table that exists at the time the call is made, and that listener only fires when a td sub-element of that table element is clicked.

$("button").click(function() {
  $("tr").append("<td>I am added after page-load time and am not targeted by load-time scripts. The listener that fires an alert does not apply to me, because I didn't exist when the <code>$('table td').click</code> code ran. However, the delegated listener still aplies, so I will turn red when you click me.</td>");
})

$("table td").on("click", function() { alert("hi"); });

$("table").delegate("td", "click", function() { $(this).css("color", "red"); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="width:70%";>
  <tr>
    <td>I am targeted by non-delegated event listeners set at page-load time. Click this text to trun this text red and see an alert.</td>
  </tr>
</table>
<button>Add another td</button>

Delegation works because when you click a child element (like a td) you've actually clicked all of its parents (like a table and the body) as well. (To compare to human person: you can't poke a person's arm without also poking that person as a whole.) When a click listener fires for a parent, the event has a target property that indicates what element was the original target of the event.

document.getElementById("theDiv").addEventListener("click", function(e) {
  if(e.target != this) {
      e.target.style.color = "red";
  }
});
<div id="theDiv">
  <span>I'm a span, inside of a div</span><br/>
  <span>I'm another span, inside of a div</span><br/>
  <span>I'm a third span, inside of a div</span>
</div>

Note in this example, we add only one listener on the <div>. When we click a <span>, the click event also applies to the parent <div>. We use event.target to allow the <div> listener to find out which of its children was clicked.

apsillers
  • 112,806
  • 17
  • 235
  • 239