81
The principles of unobtrusive JavaScript Peter-Paul Koch (ppk) http://quirksmode.org An Event Apart Boston, June 24th, 2008 Hell is other browsers - Sartre

An Event Apart Boston: Principles of Unobtrusive JavaScript

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: An Event Apart Boston: Principles of Unobtrusive JavaScript

The principles of unobtrusive JavaScript

Peter-Paul Koch (ppk)http://quirksmode.org

An Event Apart Boston, June 24th, 2008

Hell is other browsers - Sartre

Page 2: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Wikipedia: “an emerging paradigm in the JavaScript programming language.”

Me:it's just a good idea.

Page 3: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

It's not a technique

It's more like a philosophyfor using JavaScript in its context:

usable, accessible, standards-compliant web pages

Page 4: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything

Page 5: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything

Page 6: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior - Separate them - Connect them

Page 7: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior - Separate them - Connect them

Page 8: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and CSS:

<div style=”position: relative”>

Page 9: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and CSS:

<div style=”position: relative”>

No inline styles!

Page 10: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and CSS:

<div class=”container”>

div.container {position: relative;

}

Page 11: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and JavaScript:

<input onmouseover=”doSomething()” />

Page 12: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and JavaScript:

<input onmouseover=”doSomething()” />

No inline event handlers!

Page 13: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and JavaScript:

<input id=”special” />

$('special').onmouseover = function () {

doSomething();}

Page 14: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Advantages

- Ease of maintenance

Page 15: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and JavaScript:

<input id=”special” />

$('special').onmouseover = function () {

doSomething();}

Page 16: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Separation of HTML and JavaScript:

<input id=”special” />

$('special').onmouseover = $('special').onfocus = function () {

doSomething();}

Page 17: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate them

Advantages

- Ease of maintenance- The CSS and JavaScript layers can be edited simultaneously

Page 18: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior - Separate them - Connect them

Page 19: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior - Separate them - Connect them

Page 20: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

Hooks

Page 21: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

- id

document.getElementById();

Page 22: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

- id

document.getElementById('special').onmouseover = doSomething;

Page 23: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

- id

var el = document.getElementById('special');if (el) {

el.onmouseover = doSomething;}

“Is this element available?”

Page 24: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

- id- class

getElementsByClassName();or a library function

Page 25: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

- id- class

var els = document.getElementsByClassName('special')if (els.length) {

// go through all elements and do something}

Page 26: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

- id- class

Use the same hook for presentation and behavior; for CSS and JavaScript.

Page 27: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

<ol class=”dropdown“>

Now what would this <ol> be?

Surprise:it's a dropdown menu

Page 28: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

<ol class=”dropdown“>

The class is a hook for both layers.

ol.dropdown {// presentation layer

}

Page 29: An Event Apart Boston: Principles of Unobtrusive JavaScript

Connect them

<ol class=”dropdown“>

The class is a hook for both layers.

var dropdowns = $('dropdown');if (dropdowns.length) {

// initialize behavior layer}

Page 30: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior - Separate them - Connect them

Page 31: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything

Page 32: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything

Page 33: An Event Apart Boston: Principles of Unobtrusive JavaScript
Page 34: An Event Apart Boston: Principles of Unobtrusive JavaScript

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”

Page 35: An Event Apart Boston: Principles of Unobtrusive JavaScript

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”

Page 36: An Event Apart Boston: Principles of Unobtrusive JavaScript

JavaScript is always available

Nonsense!

Page 37: An Event Apart Boston: Principles of Unobtrusive JavaScript

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

Page 38: An Event Apart Boston: Principles of Unobtrusive JavaScript

JavaScript is always available

Make sure that the content and navigation of the site can be used without JavaScript.

Page 39: An Event Apart Boston: Principles of Unobtrusive JavaScript

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.

Page 40: An Event Apart Boston: Principles of Unobtrusive JavaScript

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.

Page 41: An Event Apart Boston: Principles of Unobtrusive JavaScript

JavaScript is always available

However...

Without JavaScript the page will become less user-friendly.

Can't be helped.

Page 42: An Event Apart Boston: Principles of Unobtrusive JavaScript

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.

Page 43: An Event Apart Boston: Principles of Unobtrusive JavaScript

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”

Page 44: An Event Apart Boston: Principles of Unobtrusive JavaScript

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”

Page 45: An Event Apart Boston: Principles of Unobtrusive JavaScript

Everybody uses a mouse

Nonsense!

Page 46: An Event Apart Boston: Principles of Unobtrusive JavaScript

Device independence

Page 47: An Event Apart Boston: Principles of Unobtrusive JavaScript

Take a dropdown menu:

var dropdown = {setEventHandlers: function (obj) {

obj.onmouseover = this.over;obj.onmouseout = this.out;

},over: function () {

// code},// etc

}

Page 48: An Event Apart Boston: Principles of Unobtrusive JavaScript

It doesn't work without a mouse.

var dropdown = {setEventHandlers: function (obj) {

obj.onmouseover = this.over;obj.onmouseout = this.out;

},over: function () {

// code},// etc

}

Page 49: An Event Apart Boston: Principles of Unobtrusive JavaScript

var dropdown = {setEventHandlers: function (obj) {

obj.onmouseover = this.over;obj.onmouseout = this.out;

},over: function () {

// code},// etc

}

We need evens that are fired when the user “enters” or “leaves” a link by using the keyboard.

focus and blur

Page 50: An Event Apart Boston: Principles of Unobtrusive JavaScript

var dropdown = {setEventHandlers: function (obj) {

obj.onmouseover = obj.onfocus = this.over;obj.onmouseout = obj.onblur = this.out;

},over: function () {

// code},// etc

}

Page 51: An Event Apart Boston: Principles of Unobtrusive JavaScript

var dropdown = {setEventHandlers: function (obj) {

obj.onmouseover = obj.onfocus = this.over;obj.onmouseout = obj.onblur = this.out;

},over: function () {

// code},// etc

}

Restriction: the object must be able to gain the keyboard focus.

- links- form fields

Page 52: An Event Apart Boston: Principles of Unobtrusive JavaScript

var dropdown = {setEventHandlers: function (obj) {

obj.onmouseover = obj.onfocus = this.over;obj.onmouseout = obj.onblur = this.out;

},over: function () {

// code},// etc

}

Restriction: the object must be able to gain the keyboard focus.

- links- form fields- elements with tabindex

Page 53: An Event Apart Boston: Principles of Unobtrusive JavaScript

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.

Page 54: An Event Apart Boston: Principles of Unobtrusive JavaScript

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.

Page 55: An Event Apart Boston: Principles of Unobtrusive JavaScript

Click as activate

arrow.onclick = showMenu;

Page 56: An Event Apart Boston: Principles of Unobtrusive JavaScript

Click as activate

arrow.onclick = showMenu;

1) Mouse click on the arrow

Page 57: An Event Apart Boston: Principles of Unobtrusive JavaScript

Click as activate

arrow.onclick = showMenu;

1) Mouse click on the arrow2) a) Keyboard focus on the arrow

Page 58: An Event Apart Boston: Principles of Unobtrusive JavaScript

Click as activate

arrow.onclick = showMenu;

1) Mouse click on the arrow2) a) Keyboard focus on the arrow b) Space bar on the arrow

That's two actions.

Page 59: An Event Apart Boston: Principles of Unobtrusive JavaScript

Click as activate

arrow.onclick = arrow.onfocus = showMenu;

1) Mouse click on the arrow2) Keyboard focus on the arrow b) Space bar on the arrow

Page 60: An Event Apart Boston: Principles of Unobtrusive JavaScript

Click as activate

arrow.onclick = arrow.onfocus = showMenu;

1) Mouse click on the arrow2) Keyboard focus on the arrow

The next tab will focus on the sub-menu. The user won't be able to skip it.

Page 61: An Event Apart Boston: Principles of Unobtrusive JavaScript

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.

Page 62: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-dropuses the mousemove event

Page 63: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-dropuses the mousemove event

and if there's one thing that's impossible to emulate with the keyboard

it's moving the mouse

Page 64: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-dropuses the mousemove event

How do we make this accessible?

By allowing the user to use the arrow keys.Key events.

Page 65: An Event Apart Boston: Principles of Unobtrusive JavaScript

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)

Page 66: An Event Apart Boston: Principles of Unobtrusive JavaScript

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)

Page 67: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

Page 68: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

Doesn't work.

Page 69: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

Mousemove expects mouse coordinates.The layer moves to these coordinates.

Page 70: An Event Apart Boston: Principles of Unobtrusive JavaScript

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?

Page 71: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

10px? 50px?“Move to next receptor element?”Something else that fits your interface?

Page 72: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

We have to program for two totally different situations.We need separate scripts.

Page 73: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = moveByMouse;obj.onkeydown = moveByKeys;

We have to program for two totally different situations.We need separate scripts.

Page 74: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = moveByMouse;obj.onkeydown = moveByKeys;

Yes, that's more work.

Page 75: An Event Apart Boston: Principles of Unobtrusive JavaScript

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.

Page 76: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

obj.onmousemove = moveByMouse;obj.onkeydown = moveByKeys;

Besides, I created a first draft for you.

Page 77: An Event Apart Boston: Principles of Unobtrusive JavaScript

Separate concepts

Drag-and-drop

http://quirksmode.org/js/dragdrop.html

Besides, I created a first draft for you.

Page 78: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScript

Two fundamental principles:

1) Separation of structure, presentation, and behavior 2) The script doesn't assume anything.

Page 79: An Event Apart Boston: Principles of Unobtrusive JavaScript

Unobtrusive JavaScriptIt's not that hard

Page 80: An Event Apart Boston: Principles of Unobtrusive JavaScript

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

Page 81: An Event Apart Boston: Principles of Unobtrusive JavaScript

Questions?