Skip to content

Commit be8e146

Browse files
committed
Event Delegation: Rewrite to fix typos and grammer, make things clearer, and clean up some oddly worded phrasing
1 parent c7c6684 commit be8e146

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

page/events/event-delegation.md

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,30 @@ attribution:
66
- jQuery Fundamentals
77
---
88

9-
Say you have to add new line items to your page, given the following HTML:
9+
## Introduction
10+
11+
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future.
12+
13+
## Example
14+
15+
For the remainder of the lesson, we will reference the following HTML structure:
1016
```
1117
<html>
1218
<body>
1319
<div id="container">
1420
<ul id="list">
15-
<li><a href="#">Item #1</a></li>
16-
<li><a href="http://somedomain.com">Item #2</a></li>
17-
<li><a href="#">Item #3</a></li>
18-
<li>...</li>
19-
<li><a href="http://someotherdomain.com">Item #100</a></li>
21+
<li><a href="http://domain1.com">Item #1</a></li>
22+
<li><a href="/local/path/1">Item #2</a></li>
23+
<li><a href="/local/path/2">Item #3</a></li>
24+
<li><a href="http://domain4.com">Item #4</a></li>
2025
</ul>
2126
</div>
2227
</body>
2328
</html>
2429
```
2530

26-
We need to attach the same event handler to multiple elements. In this example we want to attach an event that will log the text of the anchor tag to the console whenever it is clicked.
31+
When an anchor in our `#list` group is clicked, we want to log its text to the console. Normally we could directly bind to the click event of each anchor using the `.on()` method:
2732

28-
We can attach a direct bind click event to each `<li>` using the `.on()` method, that will alert the text inside of it by doing the following:
2933
```
3034
// attach a directly bound event
3135
$( "#list a" ).on( "click", function( event ) {
@@ -34,55 +38,65 @@ $( "#list a" ).on( "click", function( event ) {
3438
});
3539
```
3640

37-
While this works perfectly fine, there are drawbacks. Consider this:
41+
While this works perfectly fine, there are drawbacks. Consider what happens when we add a new anchor after having already bound the above listener:
42+
3843
```
3944
// add a new element on to our existing list
40-
$( "#list" ).append( "<li><a href=\"http://newsite.com\">Item #101</a></li>" );
45+
$( "#list" ).append( "<li><a href='http://newdomain.com'>Item #5</a></li>" );
4146
```
42-
If we were to click our newly added item, nothing would happen. This is because of the directly bound event that we attached previously. Direct events are only attached to elements at the time we called the `.on()` method for our existing collection of `<a>`'s, that is only the `<a>`'s that were found when we call `$()`.
47+
48+
If we were to click our newly added item, nothing would happen. This is because of the directly bound event handler that we attached previously. Direct events are only attached to elements at the time the `.on()` method is called. In this case, since our new anchor did not exist when `.on()` was called, it does not get the event handler.
4349

4450
## Event Propagation
45-
Understanding how events propagate is an important factor in being able to leverage Event Delegation. Any time an anchor tags is clicked, a *click* event is fired for the:
51+
52+
Understanding how events propagate is an important factor in being able to leverage Event Delegation. Any time one of our anchor tags is clicked, a *click* event is fired for that anchor, and then bubbles up the DOM tree, triggering each of its parent click event handlers:
4653

4754
* `<a>`
4855
* `<li>`
49-
* `<ul>`
50-
* `<div>`
56+
* `<ul #list>`
57+
* `<div #container>`
5158
* `<body>`
5259
* `<html>`
5360
* *document* root
5461

55-
Anytime one of these links is clicked you can think of it as if you were clicking the entire document body. This is called *event bubbling* or *event propagation*.
62+
This means that anytime you click one of our bound anchor tags, you are effectively clicking the entire document body! This is called *event bubbling* or *event propagation*.
63+
64+
Since we know how events bubble, we can create a *delegated* event:
5665

57-
Since we know how events bubble we can created a delegated event that listens for a specific event to happen on our element
5866
```
5967
// attach a delegated event
6068
$( "#list" ).on( "click", "a", function( event ) {
6169
event.preventDefault();
6270
console.log( $( this ).text() );
6371
});
6472
```
65-
Notice for the second parameter to the `.on()` method we are telling it which selector to listen for. Now when a *click* event is triggered on our `<ul>`, our delegated event will check to see if the triggering element matches our selector (`"a"`). If it does, our anonymous function will execute. We have now attached a single *click* event listener to our `<ul>` instead of an unknown number of directly bound events on our `<a>`'s.
6673

67-
Now lets say that whenever a link is clicked we want to check and see if the `href` attribute starts with "http" and if it does we want to set the `target` attribute to `_blank`.
74+
Notice how we have moved the `a` part from the selector to the second parameter position of the `.on()` method. This second, selector parameter tells the handler to listen for the specified event, and when it hears it, check to see if the triggering element for that event matches the second parameter. In this case, the triggering event is our anchor tag, which matches that parameter. Since it matches, our anonymous function will execute. We have now attached a single *click* event listener to our `<ul>` that will listen for clicks on its children anchors, instead of attaching an unknown number of directly bound events to the existing anchor tags only.
75+
76+
### Using the Triggering Element
77+
78+
What if we wanted to open the link in a new window if that link is an external one (as denoted here by beginning with "http")?
79+
6880
```
6981
// attach a delegated event
7082
$( "#list" ).on( "click", "a", function( event ) {
7183
var $elem = $( this );
72-
if ( $elem.is( "[href^=http]" ) ) {
84+
if ( $elem.is( "[href^='http']" ) ) {
7385
$elem.attr( "target", "_blank" );
7486
}
7587
});
7688
```
77-
This simply passes the `.is()` method a selector to see if the element's `href` attributes starts with "http". Also we have removed the `event.preventDefault();` statement, this is because we want the default action to happen (which is to following the `href`)
7889

79-
We can actually take this a step further and make our code simpler and more concise by allowing the selector argument to `.on()` do our logic for us.
90+
This simply passes the `.is()` method a selector to see if the `href` attribute of the element starts with "http". We have also removed the `event.preventDefault();` statement as we want the default action to happen (which is to follow the `href`).
91+
92+
We can actually simplify our code by allowing the selector parameter of `.on()` do our logic for us:
93+
8094
```
8195
// attach a delegated event with a more refined selector
82-
$( "#list" ).on( "click", "a[href^=http]", function( event ) {
96+
$( "#list" ).on( "click", "a[href^='http']", function( event ) {
8397
$( this ).attr( "target", "_blank" );
8498
});
8599
```
86100

87101
##Summary
88-
Event delegation refers to the process of using event bubbling to handle events at a higher level in the DOM than the element on which the event originated. It allows us to attach a single event listener for elements that exist now or in the future.
102+
Event delegation refers to the process of using event propagation (bubbling) to handle events at a higher level in the DOM than the element on which the event originated. It allows us to attach a single event listener for elements that exist now or in the future.

0 commit comments

Comments
 (0)