The Fine Art of JavaScript Event Handling Yorick Phoenix slides: bit.ly/FineArtJSEvents yorick@issio.net about.me/yorickphoenix | @scribblings | github.com/yphoenix
General Dev. Philosophy • Nothing is ever what it seems. • Expect the unexpected. • Code Defensively. • Use Good Tools
 (build them if you need to).
Quick Event Recap • User interaction creates events. • Which event depends on the element and the action. • DOM Level 0 and DOM Level 2 Models. • Legacy IE and DOM Event Models. • jQuery is your friend.
abort afterscriptexecute animatiend animatiiterati animatistart autocomplete autocompleteerror beforecopy beforecut beforepaste beforescriptexecute beforeunload blur cancel canplay canplaythrough change click close copy ctextmenu cuechange cut dblclick drag dragend dragenter dragleave dragover dragstart drop duratichange emptied ended error focus hashchange input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart message mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup mousewheel offline online pagehide pageshow paste pause play playing popstate progress ratechange reset resize scroll search seeked seeking select selectstart show stalled storage submit suspend timeupdate toggle transitiend unload volumechange waiting wheel etc …
DOM 0 <button onclick="alert('Hello, World!')"> Click Me! </button> https://jsfiddle.net/hhj9uu8x/ • No separation of UI and Event handling. • Of limited use due to limited power, flexibility and scaleability.
DOM 2 & 3 <button id="moon">Click Me!</button> $('#moon').click( function(evt) { alert("Hello, world"); }); https://jsfiddle.net/0dqc9s8p/
<Element> mouseenter mousemove mouseleave mousedown [blur] [focusout] [focus] [focusin] mouseup click
event caveats • Don't expect to get the events in the same order. • Don't expect to get all of the same events. • Don't expect the fields of the event object to be complete or correct. • Each Browser / platform / version writes their own rules.
Not Sure which events? TRY IT EXPERIMENT
detecting user hit • Don't look at mousedown or mouseup events. • look for 'click' events. • This works for touch devices. • This works for assisted devices.
click event gotchas • disabled buttons receive clicks in IE • readonly text fields get click events • readonly or disabled div elements get click events
detecting content change • Don't look at click, keydown, keyup, keypress, etc events. • look for 'change' or 'input' events. • This works for touch devices. • This works for assisted devices.
input vs change • input events indicate that an element received some input somehow. • a change event (normally) indicates that an element has finished changing. • change events often fire after loss of focus.
input event gotchas • checkboxes don't get input events • input type="file" // receives input events in IE • Editable Divs don't get input events in IE but do everywhere else, you have to use keyPress too (ugh)
change event gotchas • unset radio buttons don't get a change event • some elements send an input and change event for every user input • input type="date" or "time" • input type="range" // Firefox only
touch events • Get mapped to mouse & click events • touchstart, touchmove, touchend • mouseover, mousemove, mousedown, mouseup, click • 300ms delay
avoiding the 300ms delay • <meta name="viewport"
 content="width=device-width, user-scalable=no"> • Handle touchstart, touchmove, touchend events • Use a library: FTLabs FastClick or Tappy • http://www.sitepoint.com/5-ways-prevent-300ms- click-delay-mobile-devices/
too many event handlers? • if you had a grid of 100 elements and wanted to detect a click on each element? • How many event handlers would you need? <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div>
too many event handlers? $('.tile').click( function() { alert($(this).text()); }); • 100 click handlers, one for every Tile Element. <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div> • How many does this install?
event bubbling is better $('.box').on('click', function(evt) { alert($(evt.target).text()); }); • One event handler on the surrounding box element. <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div> • How many does this install?
event bubbling? • All events are targeted at an element. • If that element doesn't have an event handler (that completely handles the event). • The event is offered to event handlers of the parent element, and its parent, etc. • Until the top of the hierarchy is reached (document) • Or an event handler indicates that bubbling should stop.
bubble example? • a click on a tile sends a click event to the event handler for that element. • then a click event is sent to the box element. • than a click event is sent to it's parent etc. <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div>
stopping the bubble • return 'false' as the result of the event handler. • call the events stopImmediatePropagation() function. $('.Tile').click( function(evt) { alert('Tile: ' + $(this).text()); evt.stopImmediatePropagation(); // evt.cancelBubble for IE });
stopping default behavior • Some elements have default behavior such as submitting the form on the page • You can prevent this either on the element or when a form receives a 'submit' event. $('#submit').click( function(evt) { if (!confirm('Reset Fields?')) { evt.preventDefault(); // IE: evt.returnValue = false; } });
event bubble gotchas • all events bubble except for: • focus • blur • If you use jQuery you can use focusin and focusout events if you need ones that bubble.
contents of an event { charCode: integer
 keyCode: integer 
 currentTarget: EventTarget // not defined in IE
 target: EventTarget // srcElement in IE
 clientX, clientY: long
 offsetX, offsetY: integer
 pageX, pageY: integer // not in IE
 timeStamp: unsigned long // FireFox, iOS,
 IE issues
 type: string
 ... }
charCode / keyCode • charCode:keyPress events (printable chars) • keyCode: keyDown / keyUp (virtual code) • keyDown / keyUp can be different keyCodes. • Also see: altKey, ctrlKey, metaKey, shiftKey
target / currentTarget • target is the element the event was "fired" at • currentTarget is the element that has an event handler that is processing that event target: <div class="Tile">68 </div> currentTarget: <div class="Box">… </div> $('.Box').on('click', function(evt){…}); Legacy IE uses srcElement instead of target
client / offset / pageX,Y Position of mouse / touch relative to: • clientX/Y: window, regardless of whether the page is scrolled • offsetX/Y: target element • pageX/Y: page, consistent as the page is scrolled • screenX/Y: top left of monitor
 FireFox only recently started supporting offsetX Legacy IE Support is mixed for some of these jQuery is your friend, emulates what is missing
 (most of the time).
timeStamp • Time event occurred, in milliseconds! • If only that was the case! • Might be in milliseconds, might be some other number range. • Often it is zero. • Generally the numbers get bigger, but be very very careful with assumptions about timeStamp.
triggering events • You can fake events by triggering them on elements: $('#MyButton').click(); $('#MyForm').submit(); $('#MyInputField').focus(); • You can pass characters, etc if you construct your own events. • You can roll your own events or let a library (eg: jQuery) handle it for you.
custom events • You can invent your own events, send and receive them:
 $('#MyButton).on('colorChange',
 function(evt, newColor)
 {
 $(this).css('background-color', newColor); }); $('#MyButton').trigger('colorChange', ['blue']);

Sites w3schools.com/jsref/dom_obj_event.asp api.jquery.com/category/events/ caniuse.com
Tools Chrome Debugging Tools Safari iOS Debugger / Emulator github.com/yphoenix/jsEventTracer
On the Fly Tracer $.getScript('http://yphoenix.github.io/ jsEventTracer/Demo/jsEventTracer.js'); // OR (function(u) {var s=document.createElement("script");s.setAttribute(" type","text/ javascript");s.setAttribute("src",u);document.getElement sByTagName("head")[0].appendChild(s);})('http:// yphoenix.github.io/jsEventTracer/Demo/ jsEventTracer.js');
Books JavaScript: The Good Parts JavaScript: The Definitive Guide JavaScript Pocket Reference Secrets of the JavaScript Ninja
Lint JSLint.com JSHint.com ESLint.org FlowType.org
General Dev. Philosophy • Nothing is ever what it seems. • Expect the unexpected. • Code Defensively. • Use Good Tools
 (build them if you need to).
Q & A Yorick Phoenix slides: bit.ly/FineArtJSEvents yorick@issio.net about.me/yorickphoenix | @scribblings | github.com/yphoenix

The Fine Art of JavaScript Event Handling

  • 1.
    The Fine Artof JavaScript Event Handling Yorick Phoenix slides: bit.ly/FineArtJSEvents yorick@issio.net about.me/yorickphoenix | @scribblings | github.com/yphoenix
  • 2.
    General Dev. Philosophy •Nothing is ever what it seems. • Expect the unexpected. • Code Defensively. • Use Good Tools
 (build them if you need to).
  • 3.
    Quick Event Recap •User interaction creates events. • Which event depends on the element and the action. • DOM Level 0 and DOM Level 2 Models. • Legacy IE and DOM Event Models. • jQuery is your friend.
  • 4.
  • 5.
    DOM 0 <button onclick="alert('Hello,World!')"> Click Me! </button> https://jsfiddle.net/hhj9uu8x/ • No separation of UI and Event handling. • Of limited use due to limited power, flexibility and scaleability.
  • 6.
    DOM 2 &3 <button id="moon">Click Me!</button> $('#moon').click( function(evt) { alert("Hello, world"); }); https://jsfiddle.net/0dqc9s8p/
  • 7.
  • 8.
    event caveats • Don'texpect to get the events in the same order. • Don't expect to get all of the same events. • Don't expect the fields of the event object to be complete or correct. • Each Browser / platform / version writes their own rules.
  • 9.
    Not Sure whichevents? TRY IT EXPERIMENT
  • 10.
    detecting user hit •Don't look at mousedown or mouseup events. • look for 'click' events. • This works for touch devices. • This works for assisted devices.
  • 11.
    click event gotchas •disabled buttons receive clicks in IE • readonly text fields get click events • readonly or disabled div elements get click events
  • 12.
    detecting content change •Don't look at click, keydown, keyup, keypress, etc events. • look for 'change' or 'input' events. • This works for touch devices. • This works for assisted devices.
  • 13.
    input vs change •input events indicate that an element received some input somehow. • a change event (normally) indicates that an element has finished changing. • change events often fire after loss of focus.
  • 14.
    input event gotchas •checkboxes don't get input events • input type="file" // receives input events in IE • Editable Divs don't get input events in IE but do everywhere else, you have to use keyPress too (ugh)
  • 15.
    change event gotchas •unset radio buttons don't get a change event • some elements send an input and change event for every user input • input type="date" or "time" • input type="range" // Firefox only
  • 16.
    touch events • Getmapped to mouse & click events • touchstart, touchmove, touchend • mouseover, mousemove, mousedown, mouseup, click • 300ms delay
  • 17.
    avoiding the 300msdelay • <meta name="viewport"
 content="width=device-width, user-scalable=no"> • Handle touchstart, touchmove, touchend events • Use a library: FTLabs FastClick or Tappy • http://www.sitepoint.com/5-ways-prevent-300ms- click-delay-mobile-devices/
  • 18.
    too many eventhandlers? • if you had a grid of 100 elements and wanted to detect a click on each element? • How many event handlers would you need? <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div>
  • 19.
    too many eventhandlers? $('.tile').click( function() { alert($(this).text()); }); • 100 click handlers, one for every Tile Element. <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div> • How many does this install?
  • 20.
    event bubbling isbetter $('.box').on('click', function(evt) { alert($(evt.target).text()); }); • One event handler on the surrounding box element. <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div> • How many does this install?
  • 21.
    event bubbling? • Allevents are targeted at an element. • If that element doesn't have an event handler (that completely handles the event). • The event is offered to event handlers of the parent element, and its parent, etc. • Until the top of the hierarchy is reached (document) • Or an event handler indicates that bubbling should stop.
  • 22.
    bubble example? • aclick on a tile sends a click event to the event handler for that element. • then a click event is sent to the box element. • than a click event is sent to it's parent etc. <div id="box"> <div class=tile>0</div> <div class=tile>1</div> <div class=tile>2</div> … <div class=tile>99</div> </div>
  • 23.
    stopping the bubble •return 'false' as the result of the event handler. • call the events stopImmediatePropagation() function. $('.Tile').click( function(evt) { alert('Tile: ' + $(this).text()); evt.stopImmediatePropagation(); // evt.cancelBubble for IE });
  • 24.
    stopping default behavior •Some elements have default behavior such as submitting the form on the page • You can prevent this either on the element or when a form receives a 'submit' event. $('#submit').click( function(evt) { if (!confirm('Reset Fields?')) { evt.preventDefault(); // IE: evt.returnValue = false; } });
  • 25.
    event bubble gotchas •all events bubble except for: • focus • blur • If you use jQuery you can use focusin and focusout events if you need ones that bubble.
  • 26.
    contents of anevent { charCode: integer
 keyCode: integer 
 currentTarget: EventTarget // not defined in IE
 target: EventTarget // srcElement in IE
 clientX, clientY: long
 offsetX, offsetY: integer
 pageX, pageY: integer // not in IE
 timeStamp: unsigned long // FireFox, iOS,
 IE issues
 type: string
 ... }
  • 27.
    charCode / keyCode •charCode:keyPress events (printable chars) • keyCode: keyDown / keyUp (virtual code) • keyDown / keyUp can be different keyCodes. • Also see: altKey, ctrlKey, metaKey, shiftKey
  • 28.
    target / currentTarget •target is the element the event was "fired" at • currentTarget is the element that has an event handler that is processing that event target: <div class="Tile">68 </div> currentTarget: <div class="Box">… </div> $('.Box').on('click', function(evt){…}); Legacy IE uses srcElement instead of target
  • 29.
    client / offset/ pageX,Y Position of mouse / touch relative to: • clientX/Y: window, regardless of whether the page is scrolled • offsetX/Y: target element • pageX/Y: page, consistent as the page is scrolled • screenX/Y: top left of monitor
 FireFox only recently started supporting offsetX Legacy IE Support is mixed for some of these jQuery is your friend, emulates what is missing
 (most of the time).
  • 30.
    timeStamp • Time eventoccurred, in milliseconds! • If only that was the case! • Might be in milliseconds, might be some other number range. • Often it is zero. • Generally the numbers get bigger, but be very very careful with assumptions about timeStamp.
  • 31.
    triggering events • Youcan fake events by triggering them on elements: $('#MyButton').click(); $('#MyForm').submit(); $('#MyInputField').focus(); • You can pass characters, etc if you construct your own events. • You can roll your own events or let a library (eg: jQuery) handle it for you.
  • 32.
    custom events • Youcan invent your own events, send and receive them:
 $('#MyButton).on('colorChange',
 function(evt, newColor)
 {
 $(this).css('background-color', newColor); }); $('#MyButton').trigger('colorChange', ['blue']);

  • 33.
  • 34.
    Tools Chrome Debugging Tools SafariiOS Debugger / Emulator github.com/yphoenix/jsEventTracer
  • 35.
    On the FlyTracer $.getScript('http://yphoenix.github.io/ jsEventTracer/Demo/jsEventTracer.js'); // OR (function(u) {var s=document.createElement("script");s.setAttribute(" type","text/ javascript");s.setAttribute("src",u);document.getElement sByTagName("head")[0].appendChild(s);})('http:// yphoenix.github.io/jsEventTracer/Demo/ jsEventTracer.js');
  • 36.
    Books JavaScript: The GoodParts JavaScript: The Definitive Guide JavaScript Pocket Reference Secrets of the JavaScript Ninja
  • 37.
  • 38.
    General Dev. Philosophy •Nothing is ever what it seems. • Expect the unexpected. • Code Defensively. • Use Good Tools
 (build them if you need to).
  • 39.
    Q & A YorickPhoenix slides: bit.ly/FineArtJSEvents yorick@issio.net about.me/yorickphoenix | @scribblings | github.com/yphoenix