275 lines
20 KiB
HTML
275 lines
20 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
<html>
|
|
<head>
|
|
<title>YUI Library Examples: Event Utility: Using Event Utility and Event Delegation to Improve Performance</title>
|
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
|
<link rel="stylesheet" type="text/css" href="../../assets/yui.css" >
|
|
|
|
<style>
|
|
/*Supplemental CSS for the YUI distribution*/
|
|
#custom-doc { width: 95%; min-width: 950px; }
|
|
#pagetitle {background-image: url(../../assets/bg_hd.gif);}
|
|
#pagetitle h1 {background-image: url(../../assets/title_h_bg.gif);}
|
|
|
|
</style>
|
|
|
|
<link rel="stylesheet" type="text/css" href="../../assets/dpSyntaxHighlighter.css">
|
|
<!--Script and CSS includes for YUI dependencies on this page-->
|
|
<link rel="stylesheet" type="text/css" href="../../build/logger/assets/skins/sam/logger.css" />
|
|
<link rel="stylesheet" type="text/css" href="../../build/button/assets/skins/sam/button.css" />
|
|
<script type="text/javascript" src="../../build/yahoo/yahoo-min.js"></script>
|
|
<script type="text/javascript" src="../../build/event/event-debug.js"></script>
|
|
<script type="text/javascript" src="../../build/dom/dom-min.js"></script>
|
|
<script type="text/javascript" src="../../build/logger/logger-min.js"></script>
|
|
<script type="text/javascript" src="../../build/element/element-beta-min.js"></script>
|
|
<script type="text/javascript" src="../../build/button/button-min.js"></script>
|
|
|
|
|
|
<!--begin custom header content for this example-->
|
|
<style>
|
|
#list li {cursor:pointer;}
|
|
</style>
|
|
|
|
|
|
<!--end custom header content for this example-->
|
|
|
|
|
|
</head>
|
|
<body id="yahoo-com" class=" yui-skin-sam">
|
|
<div id="custom-doc" class="yui-t2">
|
|
<div id="hd">
|
|
<div id="ygunav">
|
|
<p><em>
|
|
<a href="http://developer.yahoo.com">Yahoo! Developer Network Home</a> <i> - </i>
|
|
<a href="http://help.yahoo.com/help/us/ysearch">Help</a>
|
|
</em>
|
|
</p>
|
|
<form action="http://search.yahoo.com/search"><label for="ygsp">YDN Site Search</label>
|
|
<input name="vs" type="hidden" value="developer.yahoo.com">
|
|
<input name="fr" type="hidden" value="ush-myweb">
|
|
<input id="ygsp" name="va" size="22">
|
|
<input type="submit" value="Search" class="ygbt"></form>
|
|
</div>
|
|
<div id="ygma"><a href="../../"><img src="../../assets/yui.gif" border="0" width="378" height="28"></a></div>
|
|
<div id="pagetitle"><h1>YUI Library Examples: Event Utility: Using Event Utility and Event Delegation to Improve Performance</h1></div>
|
|
</div>
|
|
<div id="bd">
|
|
<div id="yui-main">
|
|
<div class="yui-b">
|
|
<div class="yui-ge">
|
|
<div class="yui-u first example">
|
|
|
|
<div class="promo">
|
|
<h1>Event Utility: Using Event Utility and Event Delegation to Improve Performance</h1>
|
|
|
|
<div class="exampleIntro">
|
|
<p>Event delegation is a technique whereby you use a single event handler on a parent element to listen for interactions that affect the parent's descendant elements; because events on the descendant elements will bubble up to the parent, this can be a reliable and extremely efficient mitigation strategy for reducing the number of resource-consuming event handlers you have on any given page. (<a href="http://yuiblog.com/blog/2007/01/17/event-plan/">You can read more about Event Delegation in this YUIBlog article</a>.)</p>
|
|
|
|
<p>In the example below, mousing over or clicking on the list items will report their ID attributes in the Logger window on the right side of the screen. Because we're using event delegation, only one event listener is needed for each type of event (<code>click</code> and <code>mouseover</code>) to handle the event response for <code>n</code> list items. Even if there were 100 list items, we'd still just need one event handler per event type.</p>
|
|
</div>
|
|
|
|
<div class="example-container module ">
|
|
<div id="example-canvas" class="bd">
|
|
|
|
|
|
<!--BEGIN SOURCE CODE FOR EXAMPLE =============================== -->
|
|
|
|
<div id="container">
|
|
<ul id="list">
|
|
<li id="li-1">List Item 1</li>
|
|
<li id="li-2">List Item 2</li>
|
|
<li id="li-3">List Item 3</li>
|
|
<li id="li-4">List Item 4</li>
|
|
<li id="li-5">List Item 5</li>
|
|
<li id="li-6">List Item 6</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<script>
|
|
|
|
(function() {
|
|
|
|
function clickHandler(e) {
|
|
//get the resolved (non-text node) target:
|
|
var elTarget = YAHOO.util.Event.getTarget(e);
|
|
//walk up the DOM tree looking for an <li>
|
|
//in the target's ancestry; desist when you
|
|
//reach the container div
|
|
while (elTarget.id != "container") {
|
|
//are you an li?
|
|
if(elTarget.nodeName.toUpperCase() == "LI") {
|
|
//yes, an li: so write out a message to the log
|
|
YAHOO.log("The clicked li had an id of " + elTarget.id, "info", "clickExample");
|
|
//and then stop looking:
|
|
break;
|
|
} else {
|
|
//wasn't the container, but wasn't an li; so
|
|
//let's step up the DOM and keep looking:
|
|
elTarget = elTarget.parentNode;
|
|
}
|
|
}
|
|
}
|
|
//attach clickHandler as a listener for any click on
|
|
//the container div:
|
|
YAHOO.util.Event.on("container", "click", clickHandler);
|
|
|
|
function mouseHandler(e) {
|
|
var elTarget = YAHOO.util.Event.getTarget(e);
|
|
while (elTarget.id != "container") {
|
|
if(elTarget.nodeName.toUpperCase() == "LI") {
|
|
YAHOO.log("The li that was mousedover had an id of " + elTarget.id, "info", "mouseExample");
|
|
break;
|
|
} else {
|
|
elTarget = elTarget.parentNode;
|
|
}
|
|
}
|
|
}
|
|
YAHOO.util.Event.on("container", "mouseover", mouseHandler);
|
|
YAHOO.log("The example has loaded. As you interact with the example, you will see log messages appear here in the logger console.", "info", "example");
|
|
|
|
})();
|
|
|
|
</script>
|
|
<!--END SOURCE CODE FOR EXAMPLE =============================== -->
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<h2 class="first">Event Delegation and the YUI Event Utility</h2>
|
|
|
|
<p>Event delegation refers to the use of a single event listener on a parent object to listen for events happening on its children (or deeper descendants). Event delegation allows developers to be sparse in their application of event listeners while still reacting to events as they happen on highly specific targets. This proves to be a key strategy for maintaining high performance in event-rich web projects, where the creation of hundreds of event listeners can quickly degrade performance.</p>
|
|
|
|
<p>This example illustrates the use of event delegation (via the <a href="http://developer.yahoo.com/yui/event/">Event Utility</a>) on both <code>click</code> and <code>mouseover</code> events. The problem we will solve here involves reacting to <code>click</code> and <code>mouseover</code> events on list items. We will assume that there can be many list items and that we want to be frugal in applying event listeners. At the same time, we want to know exactly which <code><li></code> was involved in a <code>click</code> or <code>mouseover</code> event.</p>
|
|
<p>To do this, we'll rely on DOM event bubbling — the process by which an event progresses from its direct target up through the target's node ancestry until it reaches the <code>window</code> object. The graphic below may help to illustrate the flow: In this case, we'll count on the fact that a click or a mouseover on (A) the text node <em>within</em> an <code><li> </code> progresses to the <code><li></code> element itself (B), then to the <code><ul></code> element (C), and then to the list's parent <code><div></code> (D) and so on up the document:</p>
|
|
<p><img src="assets/eventdelegation.gif"></p>
|
|
<p>Because events flow this way, we can count on events happening to our <code><li>s</code> bubbling up to our <div> whose ID attribute is "container."</p>
|
|
<p>We'll start with some structural markup — a <code><div></code> containing a <code><ul></code> with 6 <code><li></code> children. Note that our list items have ID attributes — this gives us a way to uniquely identify them when we process <code>click</code>s and <code>mouseover</code>s at the container level. </p>
|
|
<textarea name="code" class="HTML" cols="60" rows="1"><div id="container">
|
|
<ul id="list">
|
|
<li id="li-1">List Item 1</li>
|
|
<li id="li-2">List Item 2</li>
|
|
<li id="li-3">List Item 3</li>
|
|
<li id="li-4">List Item 4</li>
|
|
<li id="li-5">List Item 5</li>
|
|
<li id="li-6">List Item 6</li>
|
|
</ul>
|
|
</div></textarea>
|
|
|
|
<p>We'll use the <a href="http://developer.yahoo.com/yui/logger/">YUI Logger Control</a> as the reporting mechanism for our event handlers, so this example begins its script by creating a LogReader instance and rendering it into the document body when the <code>window</code>'s <code>load</code> event fires:</p>
|
|
|
|
<textarea name="code" class="JScript" cols="60" rows="1">//create log reader instance on pageload
|
|
function loggerInit() {
|
|
var myLogReader = new YAHOO.widget.LogReader();
|
|
}
|
|
//on is an alias for addListener
|
|
YAHOO.util.Event.on(window, "load", loggerInit);</textarea>
|
|
|
|
<p>Now we'll add an event handler to the container <code><div></code>, listening for any clicks within its bounds. We're only really interested in clicks on <code><li></code>s, though; when we get one of those, we'll write out a message to the Logger.</p>
|
|
|
|
<textarea name="code" class="JScript" cols="60" rows="1">function clickHandler(e) {
|
|
//get the resolved (non-text node) target:
|
|
var elTarget = YAHOO.util.Event.getTarget(e);
|
|
//walk up the DOM tree looking for an <li>
|
|
//in the target's ancestry; desist when you
|
|
//reach the container div
|
|
while (elTarget.id != "container") {
|
|
//are you an li?
|
|
if(elTarget.nodeName.toUpperCase() == "LI") {
|
|
//yes, an li: so write out a message to the log
|
|
YAHOO.log("The clicked li had an id of " + elTarget.id, "info", "clickExample");
|
|
//and then stop looking:
|
|
break;
|
|
} else {
|
|
//wasn't the container, but wasn't an li; so
|
|
//let's step up the DOM and keep looking:
|
|
elTarget = elTarget.parentNode;
|
|
}
|
|
}
|
|
}
|
|
//attach clickHandler as a listener for any click on
|
|
//the container div:
|
|
YAHOO.util.Event.on("container", "click", clickHandler);</textarea>
|
|
|
|
<p>The same technique works for the <code>mousemove</code> event as well. We'll substitute <code>mousemove</code> for <code>click</code>, but make no other substantive changes:</p>
|
|
|
|
<textarea name="code" class="JScript" cols="60" rows="1">function mouseHandler(e) {
|
|
var elTarget = YAHOO.util.Event.getTarget(e);
|
|
while (elTarget.id != "container") {
|
|
if(elTarget.nodeName.toUpperCase() == "LI") {
|
|
YAHOO.log("The li that was mousedover had an id of " + elTarget.id, "info", "mouseExample");
|
|
break;
|
|
} else {
|
|
elTarget = elTarget.parentNode;
|
|
}
|
|
}
|
|
}
|
|
YAHOO.util.Event.on("container", "mouseover", mouseHandler);</textarea>
|
|
|
|
<p>In this example, we've used two event listeners with their associated memory and performance load to serve as delegates for the same two events on six list items. Instead of 12 event listeners, we now have two. And the code works regardless of the number of <code>li</code>'s used — if the list was 100 items long, we'd be saving ourselves 198 event listeners, which is enough to make a noticable difference in how your page responds. In a complicated page context, it's easy to see how this technique can dramatically reduce the number of event listeners required and thereby improve the performance of your application.</p>
|
|
</div>
|
|
<div class="yui-u">
|
|
<div id="loggerModule" class="yui-skin-sam">
|
|
<h3 class="firstContent">YUI Logger Output:</h3>
|
|
<div id="loggerDiv"></div>
|
|
</div>
|
|
|
|
|
|
<div id="examples">
|
|
<h3>Event Utility Examples:</h3>
|
|
|
|
<div id="exampleToc">
|
|
<ul>
|
|
<li><a href='../event/eventsimple.html'>Simple Event Handling and Processing</a></li><li><a href='../event/custom-event.html'>Using Custom Events</a></li><li><a href='../event/event-timing.html'>Using onAvailable, onContentReady, and onDOMReady</a></li><li class='selected'><a href='../event/event-delegation.html'>Using Event Utility and Event Delegation to Improve Performance</a></li><li><a href='../container/keylistener.html'>Implementing Container Keyboard Shortcuts with KeyListener (included with examples for Container Family)</a></li> </ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="module">
|
|
<h3>More Event Utility Resources:</h3>
|
|
<ul>
|
|
<li><a href="http://developer.yahoo.com/yui/event/">User's Guide</a> (external)</li>
|
|
<li><a href="../../docs/module_event.html">API Documentation</a></li>
|
|
|
|
|
|
<li><a href="http://yuiblog.com/assets/pdf/cheatsheets/event.pdf">Cheat Sheet PDF</a> (external)</li></ul>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="yui-b" id="tocWrapper">
|
|
<!-- TABLE OF CONTENTS -->
|
|
<div id="toc">
|
|
|
|
<ul>
|
|
<li class="sect first">Yahoo! UI Library</li><li class="item"><a title="The Yahoo! User Interface Library (YUI)" href="http://developer.yahoo.com/yui/">Home (external)</a></li><li class="item"><a title="The Yahoo! User Interface Blog" href="http://yuiblog.com">YUIBlog (external)</a></li><li class="item"><a title="The Yahoo! Group YDN-JavaScript hosts the YUI community forum" href="http://tech.groups.yahoo.com/group/ydn-javascript/">YUI Discussion Forum (external)</a></li><li class="item"><a title="The YUI Library can be downloaded from SourceForge" href="http://sourceforge.net/projects/yui/">YUI on Sourceforge (external)</a></li><li class="item"><a title="Instantly searchable API documentation for the entire YUI library." href="../../docs/index.html">API Documentation</a></li><li class="item"><a title="Examples of every YUI utility and control in action" href="../../examples/">Functional Examples</a></li><li class="item"><a title="Videos and podcasts from the YUI Team and from the Yahoo! frontend engineering community." href="http://developer.yahoo.com/yui/theater/">YUI Theater (external)</a></li><li class="item"><a title="YUI is free and open, offered under a BSD license." href="http://developer.yahoo.com/yui/license.html">YUI License (external)</a></li><li class="sect">YUI Functional Examples</li><li class="item"><a title="The YUI Animation Utility - Functional Examples" href="../../examples/animation/index.html">Animation</a></li><li class="item"><a title="The YUI AutoComplete Control - Functional Examples" href="../../examples/autocomplete/index.html">AutoComplete</a></li><li class="item"><a title="The YUI Browser History Manager - Functional Examples" href="../../examples/history/index.html">Browser History Manager</a></li><li class="item"><a title="The YUI Button Control - Functional Examples" href="../../examples/button/index.html">Button</a></li><li class="item"><a title="The YUI Calendar Control - Functional Examples" href="../../examples/calendar/index.html">Calendar</a></li><li class="item"><a title="The YUI Charts Control - Functional Examples" href="../../examples/charts/index.html">Charts (experimental)</a></li><li class="item"><a title="The YUI Color Picker Control - Functional Examples" href="../../examples/colorpicker/index.html">Color Picker</a></li><li class="item"><a title="The YUI Cookie Utility - Functional Examples" href="../../examples/cookie/index.html">Cookie (beta)</a></li><li class="item"><a title="The YUI Connection Manager (AJAX) - Functional Examples" href="../../examples/connection/index.html">Connection Manager</a></li><li class="item"><a title="The YUI Container Family (Module, Overlay, Tooltip, Panel, Dialog, SimpleDialog) - Functional Examples" href="../../examples/container/index.html">Container</a></li><li class="item"><a title="The YUI DataTable Control - Functional Examples" href="../../examples/datatable/index.html">DataTable (beta)</a></li><li class="item"><a title="The YUI Dom Collection - Functional Examples" href="../../examples/dom/index.html">Dom</a></li><li class="item"><a title="The YUI Drag & Drop Utility - Functional Examples" href="../../examples/dragdrop/index.html">Drag & Drop</a></li><li class="selected "><a title="The YUI Event Utility - Functional Examples" href="../../examples/event/index.html">Event</a></li><li class="item"><a title="The YUI Get Utility - Functional Examples" href="../../examples/get/index.html">Get</a></li><li class="item"><a title="The YUI ImageCropper Control - Functional Examples" href="../../examples/imagecropper/index.html">ImageCropper (beta)</a></li><li class="item"><a title="The YUI ImageLoader Utility - Functional Examples" href="../../examples/imageloader/index.html">ImageLoader</a></li><li class="item"><a title="The YUI JSON Utility - Functional Examples" href="../../examples/json/index.html">JSON</a></li><li class="item"><a title="The YUI Layout Manager - Functional Examples" href="../../examples/layout/index.html">Layout Manager (beta)</a></li><li class="item"><a title="The YUI Logger Control - Functional Examples" href="../../examples/logger/index.html">Logger</a></li><li class="item"><a title="The YUI Menu Control - Functional Examples" href="../../examples/menu/index.html">Menu</a></li><li class="item"><a title="The YUI Profiler Utility - Functional Examples" href="../../examples/profiler/index.html">Profiler (beta)</a></li><li class="item"><a title="The YUI ProfileViewer Control - Functional Examples" href="../../examples/profilerviewer/index.html">ProfilerViewer (beta)</a></li><li class="item"><a title="The YUI Resize Utility - Functional Examples" href="../../examples/resize/index.html">Resize (beta)</a></li><li class="item"><a title="The YUI Rich Text Editor - Functional Examples" href="../../examples/editor/index.html">Rich Text Editor (beta)</a></li><li class="item"><a title="The YUI Selector Utility - Functional Examples" href="../../examples/selector/index.html">Selector (beta)</a></li><li class="item"><a title="The YUI Slider Control - Functional Examples" href="../../examples/slider/index.html">Slider</a></li><li class="item"><a title="The YUI TabView Control - Functional Examples" href="../../examples/tabview/index.html">TabView</a></li><li class="item"><a title="The YUI TreeView Control - Functional Examples" href="../../examples/treeview/index.html">TreeView</a></li><li class="item"><a title="The YUI Uploader Utility - Functional Examples" href="../../examples/uploader/index.html">Uploader (experimental)</a></li><li class="item"><a title="The YUI YAHOO Global Object - Functional Examples" href="../../examples/yahoo/index.html">YAHOO Global Object</a></li><li class="item"><a title="The YUI Loader Utility - Functional Examples" href="../../examples/yuiloader/index.html">YUI Loader (beta)</a></li><li class="item"><a title="The YUI Test Utility - Functional Examples" href="../../examples/yuitest/index.html">YUI Test</a></li><li class="item"><a title="YUI Reset CSS - Functional Examples" href="../../examples/reset/index.html">Reset CSS</a></li><li class="item"><a title="YUI Base CSS - Functional Examples" href="../../examples/base/index.html">Base CSS</a></li><li class="item"><a title="YUI Fonts CSS - Functional Examples" href="../../examples/fonts/index.html">Fonts CSS</a></li><li class="item"><a title="YUI Grids CSS - Functional Examples" href="../../examples/grids/index.html">Grids CSS</a></li><li class="sect">YUI Articles on the YUI Website</li><li class="item"><a title="Answers to Frequently Asked Questions about the YUI Library" href="http://developer.yahoo.com/yui/articles/faq/">YUI FAQ (external)</a></li><li class="item"><a title="Yahoo!'s philosophy of Graded Browser Support" href="http://developer.yahoo.com/yui/articles/gbs/">Graded Browser Support (external)</a></li><li class="item"><a title="Reporting Bugs and Making Feature Requests for YUI Components" href="http://developer.yahoo.com/yui/articles/reportingbugs/">Bug Reports/Feature Requests (external)</a></li><li class="item"><a title="Serve YUI source files from Yahoo! -- free, fast, and simple" href="http://developer.yahoo.com/yui/articles/hosting/">Serving YUI Files from Yahoo! (external)</a></li><li class="item"><a title="Best practices for working with web services while protecting user privacy" href="http://developer.yahoo.com/security/">Security Best Practices (external)</a></li></ul>
|
|
</div>
|
|
</div>
|
|
</div><!--closes bd-->
|
|
|
|
<div id="ft">
|
|
<p class="first">Copyright © 2008 Yahoo! Inc. All rights reserved.</p>
|
|
<p><a href="http://privacy.yahoo.com/privacy/us/devel/index.html">Privacy Policy</a> -
|
|
<a href="http://docs.yahoo.com/info/terms/">Terms of Service</a> -
|
|
<a href="http://docs.yahoo.com/info/copyright/copyright.html">Copyright Policy</a> -
|
|
<a href="http://careers.yahoo.com/">Job Openings</a></p>
|
|
</div>
|
|
</div>
|
|
<script src="../../assets/dpSyntaxHighlighter.js"></script>
|
|
<script language="javascript">
|
|
dp.SyntaxHighlighter.HighlightAll('code');
|
|
</script>
|
|
|
|
<script src='../../assets/YUIexamples.js'></script>
|
|
|
|
|
|
</body>
|
|
</html>
|