SlideShare a Scribd company logo
1 of 80
Download to read offline
How
CUSTOM EVENTS
 will save the universe
Law of Demeter
“Each unit should have
only limited knowledge
  about other units.”
(we break this rule
   all the time)
the Law of Demeter is about removing
unnecessary coupling
custom events can help
  decouple your code
Broadcaster and receiver
   don’t have to know
  about one another…
… so there’s far less to mock
      in your unit tests
YOU DO HAVE
UNIT TESTS, RIGHT?
How do custom events work?
$(document).observe('custom:event', function(event) {
  var customData = event.memo;
  // stuff
});
$('troz').fire('custom:event', { foo: "bar" });
$(document).bind('customevent', function(event, customData) {
  // stuff
});
$('#troz').trigger('customevent', [{ foo: "bar" }]);
$(document).addEvent('customevent', function(event, customData) {
  // stuff
});
$('troz').fireEvent('customevent', { foo: "bar" });
BUT WHY?
Why?




       Makes testing easier
        (maybe you’ll do it now)
Why?




       Rapid prototyping
Why?




       More versatile than callbacks
Why?




       Can be bubbled/canceled
Why?




       Can handle exceptions properly
                  (in theory)
(quoth Dean Edwards)
In Prototype,
exceptions raised in one handler
  won’t affect another handler
(is this a big deal? smart people disagree)
CASE
STUDIES
Case Studies




               #
                   1
Case Studies




               (script.aculo.us 2.0)
scripty2 uses custom events…




                …as a “metronome” for effects
window.setTimeout(function() {
  document.fire('effect:heartbeat');
}, 0);
document.observe('effect:heartbeat', advanceEffectByOneFrame);
Seems pointless…
 …until you need to debug
Step through an animation
                         frame by frame

document.observe('keydown', function(event) {
  if (event.keyCode === Event.KEY_RIGHT) {
    document.fire('effect:heartbeat');
  }
});
scripty2 uses custom events…




                         …to pass messages
                        between UI widgets
S2.UI.Menu
(used by other S2.UI components)
var menu = new S2.UI.Menu();
menu.addChoice("Foo");
menu.addChoice("Bar");
someElement.insert(menu);
menu.open();
S2.UI widgets act like elements when needed, so...




    menu.observe('ui:menu:selected', function(event) {
      console.log('user clicked on:', event.memo.element);
    });
Easy to use
in any context
Button with menu
ASIDE:
Custom events are cancelable
var event = $('troz').fire('custom:event');
if (!event.stopped) performSomeDefaultAction();
(prevent all menus from appearing)




    document.observe('ui:menu:before:open', function(event) {
      event.stop();
    });
scripty2 uses custom events…




                    …as hooks for debugging
“Why aren’t these
 effects queueing
  like I expect?”
document.observe('effect:dequeued', function(event) {
  var queue = event.memo;
  console.log("Effects in queue:", queue.size());
});
You get debugging
   FOR FREE
Case Studies




               #
                   2
Case Studies




               Mouse wheel
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
}
Instead, do this:
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();
}
See also:


hashchange
Case Studies




               #
                   3
Case Studies




               User idle state
http://perfectionkills.com/detect-idle-state-with-custom-events/




                             credit: kangax

document.observe('state:idle', function() {
  turnOffBackgroundAjaxRequests();
});

document.observe('state:active', function() {
  turnOnBackgroundAjaxRequests();
});
Case Studies




               #
                   4
Case Studies




               Keyboard events
(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);
})();
Then you’d be able to do
                  something like this:
document.observe('key:left', function() { moveSlide(-1); });
document.observe('key:right', function() { moveSlide( 1); });
Case Studies




               #
                   5
Data broadcasting
Server-sent events are awesome…
     …but not universally supported
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);
});
for browsers that don’t

new Ajax.Request('/legacy/polling', {
  onComplete: function(request) {
    document.fire('data:received', request.responseJSON);
  }
});
observer works with either approach

$(document).observe('data:received', function(event) {
  doStuffWithYourData(event.memo);
});
…and your unit tests can fire dummy data

function testThatSomethingHappened() {
  document.fire('data:received', FIXTURE_DATA);
  assertSomething();
}
FAQ
FAQ




       “What if my events
      aren’t DOM-related?”
(meh)
Use the DOM anyway, I say
FAQ




      “Isn’t this overkill?”
Yes, sometimes
FAQ




      “Aren’t events slow?”
NO
Events aren’t slow;
they’re synchronous
Events are only
as slow as the handlers
   attached to them
If performance is a concern, defer
window.setTimeout(function() {
  document.fire('costly:custom:event');
}, 0);
QUESTIONS?
    Andrew Dupont
http://andrewdupont.net

More Related Content

Recently uploaded

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Dynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientationDynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientationBuild Intuit
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?Rustici Software
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceOpsTree solutions
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 

Recently uploaded (20)

Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Dynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientationDynamical Context introduction word sensibility orientation
Dynamical Context introduction word sensibility orientation
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer Experience
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 

How Custom Events Will Save the Universe