Direct and Delegated Event Handlers in jQuery

An alternate title might be: how to bind event handlers to new, or dynamically generated, table rows. When using jQuery, we attach sets of instructions to different parts of an HTML document using selectors. Suppose you wanted to attach some functionality to some text in a table, for example, when you click on a row in a table, it brings up a new table below the first table. This is actually kind of tricky, it turns out that there is a distinction between direct and delegated event handlers.

First Try: Direct Event Handling

At first blush we’d say, “Well, just attach the event in question to rows of the table in question,” and we would write something like this:

$("#someTable tr").on( "click", function() {
  bringUpNewTable()
})

This tells every row of #someTable to perform bringUpNewTable() when clicked. That’s all very well and good, until you add new rows to #someTable. The new rows, since they were not around when the existing rows were given this clickable behavior of bringing up a new table, will not respond to clicks. This is an example of direct event handling–this behavior has been given directly to the original rows of the table, and is not extended to new rows added in the future.

Second Try: Delegation Event Handling

It turns out that in order to extend the behavior to all rows of the table, including all new rows added to the table in the future, we need to write the following:

$("#someTable").on( "click", "tr", function() {
  bringUpNewTable()
})

This delegates the assignment of the row behavior to #someTable itself, instead of directly assigning the behavior to a set of individual rows. In this way, existing rows enjoy the new behavior, and newly added rows will enjoy the behavior also. Now we can update our tables willy-nilly, and not have to worry about the new rows mysteriously not working.