Successfully reported this slideshow.
Your SlideShare is downloading. ×

How Custom Events Will Save the Universe

Ad

How
CUSTOM EVENTS
 will save the universe

Ad

Law of Demeter

Ad

“Each unit should have
only limited knowledge
  about other units.”

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Loading in …3
×

Check these out next

1 of 80 Ad
1 of 80 Ad

How Custom Events Will Save the Universe

Download to read offline

Delivered at TXJS (http://texasjavascript.com) on June 5, 2010.

All the major frameworks support custom events. All framework authors love custom events and want you to use them. But few people actually do.

Custom events aren’t a gimmick. The ability to fire your own events — just like the browser fires click, mousemove, focus, and all the rest — can solve many of the problems large JS projects face.

We’ll look at a handful of recipes for integrating custom events into your own code. You’ll learn how to fire custom events in each of the major JavaScript frameworks, and explore the advantages that custom events have over a standard callback pattern.

Delivered at TXJS (http://texasjavascript.com) on June 5, 2010.

All the major frameworks support custom events. All framework authors love custom events and want you to use them. But few people actually do.

Custom events aren’t a gimmick. The ability to fire your own events — just like the browser fires click, mousemove, focus, and all the rest — can solve many of the problems large JS projects face.

We’ll look at a handful of recipes for integrating custom events into your own code. You’ll learn how to fire custom events in each of the major JavaScript frameworks, and explore the advantages that custom events have over a standard callback pattern.

Advertisement
Advertisement

More Related Content

Advertisement

How Custom Events Will Save the Universe

  1. How CUSTOM EVENTS will save the universe
  2. Law of Demeter
  3. “Each unit should have only limited knowledge about other units.”
  4. (we break this rule all the time)
  5. the Law of Demeter is about removing unnecessary coupling
  6. custom events can help decouple your code
  7. Broadcaster and receiver don’t have to know about one another…
  8. … so there’s far less to mock in your unit tests
  9. YOU DO HAVE UNIT TESTS, RIGHT?
  10. How do custom events work?
  11. $(document).observe('custom:event', function(event) { var customData = event.memo; // stuff }); $('troz').fire('custom:event', { foo: "bar" });
  12. $(document).bind('customevent', function(event, customData) { // stuff }); $('#troz').trigger('customevent', [{ foo: "bar" }]);
  13. $(document).addEvent('customevent', function(event, customData) { // stuff }); $('troz').fireEvent('customevent', { foo: "bar" });
  14. BUT WHY?
  15. Why? Makes testing easier (maybe you’ll do it now)
  16. Why? Rapid prototyping
  17. Why? More versatile than callbacks
  18. Why? Can be bubbled/canceled
  19. Why? Can handle exceptions properly (in theory)
  20. (quoth Dean Edwards)
  21. In Prototype, exceptions raised in one handler won’t affect another handler
  22. (is this a big deal? smart people disagree)
  23. CASE STUDIES
  24. Case Studies # 1
  25. Case Studies (script.aculo.us 2.0)
  26. scripty2 uses custom events… …as a “metronome” for effects
  27. window.setTimeout(function() { document.fire('effect:heartbeat'); }, 0);
  28. document.observe('effect:heartbeat', advanceEffectByOneFrame);
  29. Seems pointless… …until you need to debug
  30. Step through an animation frame by frame document.observe('keydown', function(event) { if (event.keyCode === Event.KEY_RIGHT) { document.fire('effect:heartbeat'); } });
  31. scripty2 uses custom events… …to pass messages between UI widgets
  32. S2.UI.Menu (used by other S2.UI components)
  33. var menu = new S2.UI.Menu(); menu.addChoice("Foo"); menu.addChoice("Bar"); someElement.insert(menu); menu.open();
  34. S2.UI widgets act like elements when needed, so... menu.observe('ui:menu:selected', function(event) { console.log('user clicked on:', event.memo.element); });
  35. Easy to use in any context
  36. Button with menu
  37. ASIDE: Custom events are cancelable
  38. var event = $('troz').fire('custom:event'); if (!event.stopped) performSomeDefaultAction();
  39. (prevent all menus from appearing) document.observe('ui:menu:before:open', function(event) { event.stop(); });
  40. scripty2 uses custom events… …as hooks for debugging
  41. “Why aren’t these effects queueing like I expect?”
  42. document.observe('effect:dequeued', function(event) { var queue = event.memo; console.log("Effects in queue:", queue.size()); });
  43. You get debugging FOR FREE
  44. Case Studies # 2
  45. Case Studies Mouse wheel
  46. http://adomas.org/javascript-mouse-wheel/ window.addEventListener('DOMMouseScroll', handler); window.onmousewheel = handler; function handler(event) { var delta; if (event.wheelDelta) { delta = event.wheelDelta / 120; if (window.opera) delta = -delta; // (not a joke) } else if (event.detail) { delta = -event.detail / 3; } // Do stuff with your stupid delta }
  47. Instead, do this:
  48. window.addEventListener('DOMMouseScroll', handler); window.onmousewheel = handler; function handler(event) { var delta; if (event.wheelDelta) { delta = event.wheelDelta / 120; if (window.opera) delta = -delta; // (not a joke) } else if (event.detail) { delta = -event.detail / 3; } // Fire a custom event with the normalized delta. var result = event.target.fire('mouse:wheel', { delta: delta }); if (result.stopped) event.preventDefault(); }
  49. See also: hashchange
  50. Case Studies # 3
  51. Case Studies User idle state
  52. http://perfectionkills.com/detect-idle-state-with-custom-events/ credit: kangax document.observe('state:idle', function() { turnOffBackgroundAjaxRequests(); }); document.observe('state:active', function() { turnOnBackgroundAjaxRequests(); });
  53. Case Studies # 4
  54. Case Studies Keyboard events
  55. (function() { var KEYS = {}; KEYS[Event.KEY_ESC] = "esc"; KEYS[Event.KEY_UP] = "up"; KEYS[Event.KEY_DOWN] = "down"; KEYS[Event.KEY_LEFT] = "left"; KEYS[Event.KEY_RIGHT] = "right"; // ... and so on function handler(event) { if (event.keyCode && KEYS[event.keyCode]) { event.element().fire("key:" + KEYS[event.keyCode], event); } } document.observe("keydown", handler); })();
  56. Then you’d be able to do something like this: document.observe('key:left', function() { moveSlide(-1); }); document.observe('key:right', function() { moveSlide( 1); });
  57. Case Studies # 5
  58. Data broadcasting
  59. Server-sent events are awesome… …but not universally supported
  60. for browsers that support server-sent events var eventSource = $('event_source'); eventSource.observe('server-sent-event-name', function(event) { document.fire('data:received', event.data); });
  61. for browsers that don’t new Ajax.Request('/legacy/polling', { onComplete: function(request) { document.fire('data:received', request.responseJSON); } });
  62. observer works with either approach $(document).observe('data:received', function(event) { doStuffWithYourData(event.memo); });
  63. …and your unit tests can fire dummy data function testThatSomethingHappened() { document.fire('data:received', FIXTURE_DATA); assertSomething(); }
  64. FAQ
  65. FAQ “What if my events aren’t DOM-related?”
  66. (meh)
  67. Use the DOM anyway, I say
  68. FAQ “Isn’t this overkill?”
  69. Yes, sometimes
  70. FAQ “Aren’t events slow?”
  71. NO
  72. Events aren’t slow; they’re synchronous
  73. Events are only as slow as the handlers attached to them
  74. If performance is a concern, defer window.setTimeout(function() { document.fire('costly:custom:event'); }, 0);
  75. QUESTIONS? Andrew Dupont http://andrewdupont.net

×