-
Notifications
You must be signed in to change notification settings - Fork 473
event delegation #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
event delegation #136
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Conflicts: page/events/event-delegation.md
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,52 +2,93 @@ | |
| title : Increasing Performance with Event Delegation | ||
| attribution: jQuery Fundamentals | ||
| --- | ||
| You'll frequently use jQuery to add new elements to the page, and when you do, | ||
| you may need to bind events to those new elements — events you already bound to | ||
| similar elements that were on the page originally. Instead of repeating your | ||
| event binding every time you add elements to the page, you can use event | ||
| delegation. With event delegation, you bind your event to a container element, | ||
| and then when the event occurs, you look to see which contained element it | ||
| occurred on. If this sounds complicated, luckily jQuery makes it easy with its | ||
| `$.fn.live` and `$.fn.delegate` methods. | ||
|
|
||
| While most people discover event delegation while dealing with elements added | ||
| to the page later, it has some performance benefits even if you never add more | ||
| elements to the page. The time required to bind event handlers to hundreds of | ||
| individual elements is non-trivial; if you have a large set of elements, you | ||
| should consider delegating related events to a container element. | ||
|
|
||
| <div class="note" markdown="1"> | ||
| ### Note | ||
|
|
||
| The `$.fn.live` method was introduced in jQuery 1.3, and at that time only | ||
| certain event types were supported. As of jQuery 1.4.2, the `$.fn.delegate` | ||
| method is available, and is the preferred method. | ||
| </div> | ||
|
|
||
| <div class="example" markdown="1"> | ||
| Event delegation using `$.fn.delegate` | ||
|
|
||
| $('#myUnorderedList').delegate('li', 'click', function(e) { | ||
| var $myListItem = $(this); | ||
| // ... | ||
| }); | ||
| </div> | ||
|
|
||
| <javascript caption="Event delegation using `$.fn.live`"> | ||
| $('#myUnorderedList li').live('click', function(e) { | ||
| var $myListItem = $(this); | ||
| // ... | ||
| }); | ||
| </javascript> | ||
|
|
||
| ### Unbinding Delegated Events | ||
|
|
||
| If you need to remove delegated events, you can't simply unbind them. Instead, | ||
| use `$.fn.undelegate` for events connected with `$.fn.delegate`, and `$.fn.die` | ||
| for events connected with `$.fn.live`. As with bind, you can optionally pass | ||
| in the name of the bound function.<javascript caption="Unbinding delegated events"> | ||
| $('#myUnorderedList').undelegate('li', 'click'); | ||
| $('#myUnorderedList li').die('click');</javascript> | ||
| <div class="example" markdown="1"> | ||
| </div> | ||
|
|
||
| Say you have to add new line items to your page, given the following html: | ||
| ``` | ||
| <html> | ||
| <body> | ||
| <div id="container"> | ||
| <ul id="list"> | ||
| <li> | ||
| <a href="#">Item #1</a> | ||
| </li> | ||
| <li> | ||
| <a href="http://somedomain.com">Item #2</a> | ||
| </li> | ||
| <li> | ||
| <a href="#">Item #3</a> | ||
| </li> | ||
| <li>...</li> | ||
| <li> | ||
| <a href="http://someotherdomain.com">Item #100</a> | ||
| </li> | ||
| </ul> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| We need to attach the same Event Listener to multiple elements. In this example we want to attach an event that will the log the text of the anchor tag to the console whenever it is clicked. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change "Event Listener" to "event handler", in lowercase |
||
|
|
||
| We can attach a direct bind click event to each `li` that will alert the text inside of it by doing the following: | ||
| ``` | ||
| // attach a directly bound event | ||
| $('#list a').on('click', function(event) { | ||
| event.preventDefault(); | ||
| console.log( $(this).text() ); | ||
| }); | ||
| ``` | ||
|
|
||
| While this works perfectly fine, there are drawbacks. Consider this: | ||
| ``` | ||
| // add a new element on to our existing list | ||
| $('#list').append('<li><a href="http://newsite.com">Item #101</a></li>'); | ||
| ``` | ||
| 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 `$('#list a')` | ||
|
|
||
| ## Event Propagation | ||
| 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: | ||
|
|
||
| * `a` tag | ||
| * `li` tag | ||
| * `ul` tag | ||
| * `div` tag | ||
| * `body` tag | ||
| * `html` tag | ||
| * document root | ||
|
|
||
| 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_. | ||
|
|
||
| Since we know how events bubble we can created a delegated event that listens for a specific event to happen on our element | ||
| ``` | ||
| // attach a delegated event | ||
| $('#list').on('click', 'a', function(event){ | ||
| event.preventDefault(); | ||
| console.log( $(this).text() ); | ||
| }); | ||
| ``` | ||
| 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 on our `ul` tag instead of an unknown number of direct events on our `a` tags. | ||
|
|
||
| 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`. | ||
| ``` | ||
| // attach a delegated event | ||
| $('#list').on('click', 'a', function(event){ | ||
| var $elem = $(this); | ||
| if( $elem.is('[href^=http]') ){ | ||
| $elem.attr('target', '_blank'); | ||
| } | ||
| }); | ||
| ``` | ||
| 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 followin the `href`) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "following," not "followin" :) |
||
|
|
||
| We can actually take this a step further and make our code simpiler and more concise by allowing the selector argument to `on` do our logic for us. | ||
| ``` | ||
| // attach a delegated event with a more refined selector | ||
| $('#list').on('click', 'a[href^=http]', function(event){ | ||
| $(this).attr('target', '_blank'); | ||
| }); | ||
| ``` | ||
|
|
||
| ##Summary | ||
| Event Delegation is the processing of listening for Bubbling Events. It allows us to attach a single Event Listener for elements that exist now or in the future. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace first sentence with "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." |
||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove blank line |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"list items" or "
<li>" please.Capitalize HTML