|
1 <!DOCTYPE html> |
|
2 <html lang="en"> |
|
3 <head> |
|
4 <meta charset="utf-8"> |
|
5 <title>Example: Custom Event Bubbling and Behaviors</title> |
|
6 <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic"> |
|
7 <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css"> |
|
8 <link rel="stylesheet" href="../assets/css/main.css"> |
|
9 <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css"> |
|
10 <link rel="shortcut icon" type="image/png" href="../assets/favicon.png"> |
|
11 <script src="../../build/yui/yui-min.js"></script> |
|
12 |
|
13 </head> |
|
14 <body> |
|
15 <!-- |
|
16 <a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> |
|
17 --> |
|
18 <div id="doc"> |
|
19 <div id="hd"> |
|
20 <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1> |
|
21 </div> |
|
22 |
|
23 |
|
24 <h1>Example: Custom Event Bubbling and Behaviors</h1> |
|
25 <div class="yui3-g"> |
|
26 <div class="yui3-u-3-4"> |
|
27 <div id="main"> |
|
28 <div class="content"><style type="text/css"> |
|
29 #fire { |
|
30 margin: 1em; |
|
31 } |
|
32 #log { |
|
33 border: 1px dotted #999; |
|
34 background-color: #FFF; |
|
35 } |
|
36 #log li { |
|
37 padding: 5px; |
|
38 } |
|
39 #log li highlight { |
|
40 color: #930; |
|
41 } |
|
42 </style> |
|
43 |
|
44 <div class="intro"> |
|
45 <p> |
|
46 The Custom Event framework is one of the principle communication |
|
47 mechanisms in YUI. An object can be augmented with |
|
48 <code>EventTarget</code>, enabling it to be both a host and a target |
|
49 for custom events. Custom events fire from their host and optionally |
|
50 bubble up to one or more targets. This allows you to make the |
|
51 interesting moments of your applications broadly available within a |
|
52 module, within a set of modules, or throughout a complex interface |
|
53 populated with rich elements. |
|
54 </p> |
|
55 |
|
56 <p> |
|
57 In this example, a simple custom event is illustrated: |
|
58 <code>testEvent</code>. This custom event is hosted on a Publisher |
|
59 object and bubbles up to a BubbleTarget object. |
|
60 </p> |
|
61 |
|
62 <img src="../assets/event-custom/ce-example.gif" |
|
63 alt="An illustration of the relationship between the custom event, its host, and its Bubble Target."> |
|
64 |
|
65 <p> |
|
66 Like DOM events, custom event bubbling can be stopped with |
|
67 <code>e.stopPropagation()</code> and default behavior can be suppressed with |
|
68 <code>e.preventDefault()</code>. |
|
69 </p> |
|
70 </div> |
|
71 |
|
72 <div class="example yui3-skin-sam"> |
|
73 <p> |
|
74 <button id="fire" value="Fire">Fire testEvent</button> |
|
75 </p> |
|
76 |
|
77 <div> |
|
78 <input type="checkbox" id="stopPropagation"> |
|
79 <label for="stopPropagation"> |
|
80 Stop Propagation (testEvent won't bubble to the BubbleTarget.) |
|
81 </label> |
|
82 </div> |
|
83 <div> |
|
84 <input type="checkbox" id="preventDefault"> |
|
85 <label for="preventDefault"> |
|
86 Prevent Default (testEvent's <code>defaultFn</code> won't fire.) |
|
87 </label> |
|
88 </div> |
|
89 |
|
90 <ol id="log"> |
|
91 <li>Custom Event log messages will appear here.</li> |
|
92 </ol> |
|
93 <script> |
|
94 // Bubbling events are added by the event-custom module. |
|
95 YUI().use('event-custom', 'node', function (Y) { |
|
96 |
|
97 var logger = Y.one("#log"); |
|
98 stopCheckbox = Y.one("#stopPropagation"), |
|
99 preventCheckbox = Y.one("#preventDefault"); |
|
100 |
|
101 // We'll create two classes, one to fire the event, and another to be a |
|
102 // bubble target for the other. All events from the Publisher class can |
|
103 // then be subscribed from either the Publisher instance or the BubbleTarget |
|
104 // instance that it's related to. |
|
105 function BubbleTarget() { |
|
106 Y.log("BubbleTarget constructor executed."); |
|
107 } |
|
108 |
|
109 function Publisher(bubbleTo) { |
|
110 Y.log("Publisher constructor executed."); |
|
111 |
|
112 this.init(bubbleTo); // see class prototype below |
|
113 } |
|
114 |
|
115 // Publishers need to add the provided target to their bubble chain with |
|
116 // <code>addTarget</code>. We'll do this, and publish an event, in an <code>init</code> method |
|
117 Publisher.prototype = { |
|
118 init: function (bubbleTo) { |
|
119 |
|
120 // <code>addTarget</code> is the EventTarget method to register new bubble |
|
121 // targets for this instance |
|
122 this.addTarget(bubbleTo); |
|
123 |
|
124 // It's only necessary to publish events with special configuration, |
|
125 // such as default, stop, or prevent behaviors. You can always |
|
126 // fire any event name you wish, published or unpublished. |
|
127 this.publish("testEvent", { |
|
128 // Pass an event facade to subscribers so they can call |
|
129 // e.preventDefault() and other methods. |
|
130 emitFacade: true, |
|
131 |
|
132 // An event's default behavior is defined in defaultFn. This |
|
133 // will execute unless a subscriber calls <code>e.preventDefault()</code> |
|
134 defaultFn: function () { |
|
135 Y.log("defaultFn: testEvent's defaultFn executed."); |
|
136 }, |
|
137 |
|
138 // You can react to subscribers preventing default behavior as |
|
139 // well, by defining a preventedFn. |
|
140 preventedFn: function () { |
|
141 Y.log("preventedFn: A subscriber to testEvent called preventDefault()."); |
|
142 }, |
|
143 |
|
144 // If a subscriber calls <code>e.stopPropagation()</code>, the event won't |
|
145 // bubble any further, and the stoppedFn will be called if one |
|
146 // is defined. |
|
147 stoppedFn: function () { |
|
148 Y.log("stoppedFn: A subscriber to testEvent called stopPropagation()."); |
|
149 } |
|
150 }); |
|
151 } |
|
152 }; |
|
153 |
|
154 |
|
155 // To fire events or be a bubble target, augment a class with EventTarget |
|
156 Y.augment(Publisher, Y.EventTarget); |
|
157 Y.augment(BubbleTarget, Y.EventTarget); |
|
158 |
|
159 |
|
160 // SEE IT IN ACTION |
|
161 |
|
162 var bubbleTarget = new BubbleTarget(); |
|
163 |
|
164 // You can subscribe to the "testEvent" from the BubbleTarget, even before |
|
165 // a Publisher is created |
|
166 bubbleTarget.subscribe("testEvent", function (e) { |
|
167 Y.log("testEvent fired on the BubbleTarget object."); |
|
168 }); |
|
169 |
|
170 // Create a Publisher instance, and link it to our BubbleTarget |
|
171 var publisher = new Publisher(bubbleTarget); |
|
172 |
|
173 // We can also subscribe to the testEvent on the Publisher instance. |
|
174 publisher.on("testEvent", function (e) { |
|
175 Y.log("testEvent subscriber fired on the publisher object."); |
|
176 |
|
177 if (stopCheckbox.get("checked")) { |
|
178 e.stopPropagation(); |
|
179 } |
|
180 |
|
181 if (preventCheckbox.get("checked")) { |
|
182 e.preventDefault(); |
|
183 } |
|
184 }); |
|
185 |
|
186 |
|
187 // Wire up the example button to fire the event from our publisher |
|
188 Y.one("#fire").on("click", function (e) { |
|
189 logger.empty(); // clear out the logger: |
|
190 |
|
191 publisher.fire("testEvent"); |
|
192 }); |
|
193 |
|
194 // A little supporting magic to output Y.log() statements to the screen |
|
195 Y.on("yui:log", function (e) { |
|
196 logger.append("<li>" + e.msg + "</li>"); |
|
197 }); |
|
198 |
|
199 }); |
|
200 |
|
201 </script> |
|
202 </div> |
|
203 |
|
204 <h2>Source Code</h2> |
|
205 |
|
206 <p> |
|
207 The full source code for this example follows. Read through the comments |
|
208 and code to get an understanding of how you can make use of custom events |
|
209 in your own application development. |
|
210 </p> |
|
211 |
|
212 <pre class="code prettyprint">// Bubbling events are added by the event-custom module. |
|
213 YUI().use('event-custom', 'node', function (Y) { |
|
214 |
|
215 var logger = Y.one("#log"); |
|
216 stopCheckbox = Y.one("#stopPropagation"), |
|
217 preventCheckbox = Y.one("#preventDefault"); |
|
218 |
|
219 // We'll create two classes, one to fire the event, and another to be a |
|
220 // bubble target for the other. All events from the Publisher class can |
|
221 // then be subscribed from either the Publisher instance or the BubbleTarget |
|
222 // instance that it's related to. |
|
223 function BubbleTarget() { |
|
224 Y.log("BubbleTarget constructor executed."); |
|
225 } |
|
226 |
|
227 function Publisher(bubbleTo) { |
|
228 Y.log("Publisher constructor executed."); |
|
229 |
|
230 this.init(bubbleTo); // see class prototype below |
|
231 } |
|
232 |
|
233 // Publishers need to add the provided target to their bubble chain with |
|
234 // `addTarget`. We'll do this, and publish an event, in an `init` method |
|
235 Publisher.prototype = { |
|
236 init: function (bubbleTo) { |
|
237 |
|
238 // `addTarget` is the EventTarget method to register new bubble |
|
239 // targets for this instance |
|
240 this.addTarget(bubbleTo); |
|
241 |
|
242 // It's only necessary to publish events with special configuration, |
|
243 // such as default, stop, or prevent behaviors. You can always |
|
244 // fire any event name you wish, published or unpublished. |
|
245 this.publish("testEvent", { |
|
246 // Pass an event facade to subscribers so they can call |
|
247 // e.preventDefault() and other methods. |
|
248 emitFacade: true, |
|
249 |
|
250 // An event's default behavior is defined in defaultFn. This |
|
251 // will execute unless a subscriber calls `e.preventDefault()` |
|
252 defaultFn: function () { |
|
253 Y.log("defaultFn: testEvent's defaultFn executed."); |
|
254 }, |
|
255 |
|
256 // You can react to subscribers preventing default behavior as |
|
257 // well, by defining a preventedFn. |
|
258 preventedFn: function () { |
|
259 Y.log("preventedFn: A subscriber to testEvent called preventDefault()."); |
|
260 }, |
|
261 |
|
262 // If a subscriber calls `e.stopPropagation()`, the event won't |
|
263 // bubble any further, and the stoppedFn will be called if one |
|
264 // is defined. |
|
265 stoppedFn: function () { |
|
266 Y.log("stoppedFn: A subscriber to testEvent called stopPropagation()."); |
|
267 } |
|
268 }); |
|
269 } |
|
270 }; |
|
271 |
|
272 |
|
273 // To fire events or be a bubble target, augment a class with EventTarget |
|
274 Y.augment(Publisher, Y.EventTarget); |
|
275 Y.augment(BubbleTarget, Y.EventTarget); |
|
276 |
|
277 |
|
278 // SEE IT IN ACTION |
|
279 |
|
280 var bubbleTarget = new BubbleTarget(); |
|
281 |
|
282 // You can subscribe to the "testEvent" from the BubbleTarget, even before |
|
283 // a Publisher is created |
|
284 bubbleTarget.subscribe("testEvent", function (e) { |
|
285 Y.log("testEvent fired on the BubbleTarget object."); |
|
286 }); |
|
287 |
|
288 // Create a Publisher instance, and link it to our BubbleTarget |
|
289 var publisher = new Publisher(bubbleTarget); |
|
290 |
|
291 // We can also subscribe to the testEvent on the Publisher instance. |
|
292 publisher.on("testEvent", function (e) { |
|
293 Y.log("testEvent subscriber fired on the publisher object."); |
|
294 |
|
295 if (stopCheckbox.get("checked")) { |
|
296 e.stopPropagation(); |
|
297 } |
|
298 |
|
299 if (preventCheckbox.get("checked")) { |
|
300 e.preventDefault(); |
|
301 } |
|
302 }); |
|
303 |
|
304 |
|
305 // Wire up the example button to fire the event from our publisher |
|
306 Y.one("#fire").on("click", function (e) { |
|
307 logger.empty(); // clear out the logger: |
|
308 |
|
309 publisher.fire("testEvent"); |
|
310 }); |
|
311 |
|
312 // A little supporting magic to output Y.log() statements to the screen |
|
313 Y.on("yui:log", function (e) { |
|
314 logger.append("<li>" + e.msg + "</li>"); |
|
315 }); |
|
316 |
|
317 });</pre> |
|
318 |
|
319 |
|
320 </div> |
|
321 </div> |
|
322 </div> |
|
323 |
|
324 <div class="yui3-u-1-4"> |
|
325 <div class="sidebar"> |
|
326 |
|
327 |
|
328 |
|
329 <div class="sidebox"> |
|
330 <div class="hd"> |
|
331 <h2 class="no-toc">Examples</h2> |
|
332 </div> |
|
333 |
|
334 <div class="bd"> |
|
335 <ul class="examples"> |
|
336 |
|
337 |
|
338 <li data-description="Publish an event with a default behavior, as well as behaviors for reacting to preventing the default or stopping bubbling."> |
|
339 <a href="flow-example.html">Custom Event Bubbling and Behaviors</a> |
|
340 </li> |
|
341 |
|
342 |
|
343 </ul> |
|
344 </div> |
|
345 </div> |
|
346 |
|
347 |
|
348 |
|
349 </div> |
|
350 </div> |
|
351 </div> |
|
352 </div> |
|
353 |
|
354 <script src="../assets/vendor/prettify/prettify-min.js"></script> |
|
355 <script>prettyPrint();</script> |
|
356 |
|
357 <script> |
|
358 YUI.Env.Tests = { |
|
359 examples: [], |
|
360 project: '../assets', |
|
361 assets: '../assets/event-custom', |
|
362 name: 'flow-example', |
|
363 title: 'Custom Event Bubbling and Behaviors', |
|
364 newWindow: '', |
|
365 auto: false |
|
366 }; |
|
367 YUI.Env.Tests.examples.push('flow-example'); |
|
368 |
|
369 </script> |
|
370 <script src="../assets/yui/test-runner.js"></script> |
|
371 |
|
372 |
|
373 |
|
374 </body> |
|
375 </html> |