An Event Apart Boston: Principles of Unobtrusive JavaScript

2,238 views
2,185 views

Published on

My AEA Boston presentation about the principles of unobtrusive JavaScript. Good beginners' material; advanced JavaScripters will be bored stiff.

Published in: Technology
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,238
On SlideShare
0
From Embeds
0
Number of Embeds
20
Actions
Shares
0
Downloads
77
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide

An Event Apart Boston: Principles of Unobtrusive JavaScript

  1. 1. Hell is other browsers - Sartre The principles of unobtrusive JavaScript Peter-Paul Koch (ppk) http://quirksmode.org An Event Apart Boston, June 24th, 2008
  2. 2. Unobtrusive JavaScript Wikipedia: “an emerging paradigm in the JavaScript programming language.” Me: it's just a good idea.
  3. 3. Unobtrusive JavaScript It's not a technique It's more like a philosophy for using JavaScript in its context: usable, accessible, standards- compliant web pages
  4. 4. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything
  5. 5. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything
  6. 6. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior - Separate them - Connect them
  7. 7. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior - Separate them - Connect them
  8. 8. Separate them Separation of HTML and CSS: <div style=”position: relative”>
  9. 9. Separate them Separation of HTML and CSS: <div style=”position: relative”> No inline styles!
  10. 10. Separate them Separation of HTML and CSS: <div class=”container”> div.container { position: relative; }
  11. 11. Separate them Separation of HTML and JavaScript: <input onmouseover=”doSomething()” />
  12. 12. Separate them Separation of HTML and JavaScript: <input onmouseover=”doSomething()” /> No inline event handlers!
  13. 13. Separate them Separation of HTML and JavaScript: <input id=”special” /> $('special').onmouseover = function () { doSomething(); }
  14. 14. Separate them Advantages - Ease of maintenance
  15. 15. Separate them Separation of HTML and JavaScript: <input id=”special” /> $('special').onmouseover = function () { doSomething(); }
  16. 16. Separate them Separation of HTML and JavaScript: <input id=”special” /> $('special').onmouseover = $('special').onfocus = function () { doSomething(); }
  17. 17. Separate them Advantages - Ease of maintenance - The CSS and JavaScript layers can be edited simultaneously
  18. 18. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior - Separate them - Connect them
  19. 19. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior - Separate them - Connect them
  20. 20. Connect them Hooks
  21. 21. Connect them - id document.getElementById();
  22. 22. Connect them - id document.getElementById('special'). onmouseover = doSomething;
  23. 23. Connect them - id var el = document.getElementById('special'); if (el) { el.onmouseover = doSomething; } “Is this element available?”
  24. 24. Connect them - id - class getElementsByClassName(); or a library function
  25. 25. Connect them - id - class var els = document.getElementsByClassName('special') if (els.length) { // go through all elements and do something }
  26. 26. Connect them - id - class Use the same hook for presentation and behavior; for CSS and JavaScript.
  27. 27. Connect them <ol class=”dropdown“> Now what would this <ol> be? Surprise: it's a dropdown menu
  28. 28. Connect them <ol class=”dropdown“> The class is a hook for both layers. ol.dropdown { // presentation layer }
  29. 29. Connect them <ol class=”dropdown“> The class is a hook for both layers. var dropdowns = $('dropdown'); if (dropdowns.length) { // initialize behavior layer }
  30. 30. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior - Separate them - Connect them
  31. 31. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything
  32. 32. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything
  33. 33. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything - “JavaScript is always available” - “Everybody uses a mouse”
  34. 34. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything - “JavaScript is always available” - “Everybody uses a mouse”
  35. 35. JavaScript is always available Nonsense!
  36. 36. JavaScript is always available - Primitive cell phones don't support it (sufficiently) - Speech browsers' support may be spotty - Company networks may filter out <script> tags
  37. 37. JavaScript is always available Make sure that the content and navigation of the site can be used without JavaScript.
  38. 38. JavaScript is always available Make sure that the content and navigation of the site can be used without JavaScript. The page will remain accessible in all circumstances.
  39. 39. JavaScript is always available Make sure that the content and navigation of the site can be used without JavaScript. You can use JavaScript for nice extras, though.
  40. 40. JavaScript is always available However... Without JavaScript the page will become less user-friendly. Can't be helped.
  41. 41. JavaScript is always available However... Without JavaScript the page will become less user-friendly. After all, the purpose of JavaScript is to add interactivity to a page.
  42. 42. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything - “JavaScript is always available” - “Everybody uses a mouse”
  43. 43. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything - “JavaScript is always available” - “Everybody uses a mouse”
  44. 44. Everybody uses a mouse Nonsense!
  45. 45. Device independence
  46. 46. Take a dropdown menu: var dropdown = { setEventHandlers: function (obj) { obj.onmouseover = this.over; obj.onmouseout = this.out; }, over: function () { // code }, // etc }
  47. 47. It doesn't work without a mouse. var dropdown = { setEventHandlers: function (obj) { obj.onmouseover = this.over; obj.onmouseout = this.out; }, over: function () { // code }, // etc }
  48. 48. var dropdown = { setEventHandlers: function (obj) { We need evens that are fired when obj.onmouseover = this.over; the obj.onmouseout = this.out; a link by user “enters” or “leaves” using the keyboard. }, over: function () { focus code blur // and }, // etc }
  49. 49. var dropdown = { setEventHandlers: function (obj) { obj.onmouseover = obj.onfocus = this.over; obj.onmouseout = obj.onblur = this.out; }, over: function () { // code }, // etc }
  50. 50. Restriction: var dropdown = { be able to gain the the object must setEventHandlers: function (obj) { keyboard focus. obj.onmouseover = obj.onfocus = this.over; obj.onmouseout = obj.onblur = this.out; - links }, - formfunction () { over: fields // code }, // etc }
  51. 51. Restriction: var dropdown = { be able to gain the the object must setEventHandlers: function (obj) { keyboard focus. obj.onmouseover = obj.onfocus = this.over; obj.onmouseout = obj.onblur = this.out; - links }, - formfunction () { over: fields // code - elements with tabindex }, // etc }
  52. 52. And what about click? We're in luck: the click event fires also when the user activates an element by the keyboard. click should be called activate.
  53. 53. And what about click? We're in luck: the click event fires also when the user activates an element by the keyboard. Restriction: the object must be able to gain the keyboard focus.
  54. 54. Click as activate arrow.onclick = showMenu;
  55. 55. Click as activate arrow.onclick = showMenu; 1) Mouse click on the arrow
  56. 56. Click as activate arrow.onclick = showMenu; 1) Mouse click on the arrow 2) a) Keyboard focus on the arrow
  57. 57. Click as activate arrow.onclick = showMenu; 1) Mouse click on the arrow 2) a) Keyboard focus on the arrow b) Space bar on the arrow That's two actions.
  58. 58. Click as activate arrow.onclick = arrow.onfocus = showMenu; 1) Mouse click on the arrow 2) Keyboard focus on the arrow b) Space bar on the arrow
  59. 59. Click as activate arrow.onclick = arrow.onfocus = showMenu; 1) Mouse click on the arrow 2) Keyboard focus on the arrow The next tab will focus on the sub-menu. The user won't be able to skip it.
  60. 60. Click as activate arrow.onclick = arrow.onfocus = showMenu; Generally, keyboard users need more actions to achieve the same goals as mouse users. Don't interfere too much. There are reasons for this behavior, and keyboard users are used to it.
  61. 61. Separate concepts Drag-and-drop uses the mousemove event
  62. 62. Separate concepts Drag-and-drop uses the mousemove event and if there's one thing that's impossible to emulate with the keyboard it's moving the mouse
  63. 63. Separate concepts Drag-and-drop uses the mousemove event How do we make this accessible? By allowing the user to use the arrow keys. Key events.
  64. 64. Separate concepts Drag-and-drop For detecting arrow keys (or other special keys) we need the keydown event. Not keypress. (Doesn't work in IE and Safari)
  65. 65. Separate concepts Drag-and-drop For detecting arrow keys (or other special keys) we need the keydown event. Not keypress. (Doesn't work in IE and Safari)
  66. 66. Separate concepts Drag-and-drop obj.onmousemove = obj.onkeydown = moveElement;
  67. 67. Separate concepts Drag-and-drop obj.onmousemove = obj.onkeydown = moveElement; Doesn't work.
  68. 68. Separate concepts Drag-and-drop obj.onmousemove = obj.onkeydown = moveElement; Mousemove expects mouse coordinates. The layer moves to these coordinates.
  69. 69. Separate concepts Drag-and-drop obj.onmousemove = obj.onkeydown = moveElement; The key events expect a keystroke. But what does “user hits right arrow once” mean?
  70. 70. Separate concepts Drag-and-drop obj.onmousemove = obj.onkeydown = moveElement; 10px? 50px? “Move to next receptor element?” Something else that fits your interface?
  71. 71. Separate concepts Drag-and-drop obj.onmousemove = obj.onkeydown = moveElement; We have to program for two totally different situations. We need separate scripts.
  72. 72. Separate concepts Drag-and-drop obj.onmousemove = moveByMouse; obj.onkeydown = moveByKeys; We have to program for two totally different situations. We need separate scripts.
  73. 73. Separate concepts Drag-and-drop obj.onmousemove = moveByMouse; obj.onkeydown = moveByKeys; Yes, that's more work.
  74. 74. Separate concepts Drag-and-drop obj.onmousemove = moveByMouse; obj.onkeydown = moveByKeys; But if you do it right you've got a generic drag and drop module you can use anywhere.
  75. 75. Separate concepts Drag-and-drop obj.onmousemove = moveByMouse; obj.onkeydown = moveByKeys; Besides, I created a first draft for you.
  76. 76. Separate concepts Drag-and-drop http://quirksmode.org/ js/dragdrop.html Besides, I created a first draft for you.
  77. 77. Unobtrusive JavaScript Two fundamental principles: 1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything.
  78. 78. Unobtrusive JavaScript It's not that hard
  79. 79. Need help? Chris Heilmann: http://onlinetools.org/articles/unobtrusivejavascript/ http://icant.co.uk/articles/seven-rules-of-unobtrusive-javascript/ Jeremy Keith: http://www.alistapart.com/articles/behavioralseparation and of course quirksmode.org
  80. 80. Questions?

×