95
JavaScript Events Peter-Paul Koch (ppk) http://quirksmode.org http://twitter.com/ppk Voices that Matter, 28 April 2009 Hell is other browsers - Sartre

Voices That Matter: JavaScript Events

Embed Size (px)

DESCRIPTION

My Voices That Matter JavaScript Events slideshow. Overlaps with the Yahoo! presentation for about 40%.

Citation preview

Page 1: Voices That Matter: JavaScript Events

JavaScript EventsPeter-Paul Koch (ppk)

http://quirksmode.orghttp://twitter.com/ppk

Voices that Matter, 28 April 2009

Hell is other browsers - Sartre

Page 2: Voices That Matter: JavaScript Events
Page 3: Voices That Matter: JavaScript Events

http://quirksmode.org/dom/events/

Page 4: Voices That Matter: JavaScript Events

Mouseover

and friends

Page 5: Voices That Matter: JavaScript Events

The mouseover event fires when the user's mouse enters an element .

The mouseout event fires when the user's mouse leaves an element.

Perfect support

Page 6: Voices That Matter: JavaScript Events

Dropdown menu <sigh /><ul>

<li><a href=”#”>Multimedialize</a><ul>

<li><a href=”#”>Sound</a></li><li><a href=”#”>Java applets</a></li>

</ul></li><li><a href=”#”>Ajaxify</a>

<ul><li><a href=”#”>Web 2.0</a></li><li><a href=”#”>Web 3.0</a></li><li><a href=”#”>Web 4.0b</a></li>

</ul></li></ul>

Page 7: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Page 8: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Page 9: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Event bubbling has advantages.

var dropdown = {init: function (dropdown) {

var x = dropdown.getElementsByTagName('a');for (var i=0;i<x.length;i++) {

x[i].onmouseover = mouseOver;x[i].onmouseout = mouseOut;

}}

}

Page 10: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Event bubbling has advantages.

var dropdown = {init: function (dropdown) {

var x = dropdown.getElementsByTagName('a');for (var i=0;i<x.length;i++) {

x[i].onmouseover = mouseOver;x[i].onmouseout = mouseOut;

}}

}

Page 11: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Event bubbling has advantages.

var dropdown = {init: function (dropdown) {

}}

We don't do this any more. Instead we use event delegation.

Page 12: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = mouseOver;dropdown.onmouseout = mouseOut;

}}

The event bubbles up to the <ul> anyway.

So why not handle it at that level?

Saves a lot of event handlers.

Page 13: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = mouseOver;dropdown.onmouseout = mouseOut;

}}

Works in all browsers.

Page 14: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Problem: Every mouseover or mouseout event bubbles up.

Page 15: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Page 16: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

a.mouseovera.mouseout and a.mouseovera.mouseout and a.mouseovera.mouseout

Fun! Event bubbling works. As does event delegation.

Page 17: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

a.mouseovera.mouseout and a.mouseovera.mouseout and a.mouseovera.mouseout

But has the mouse left the submenu or not?!

Page 18: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;

},mouseOut: function (e) {

if (this mouseout is important) {this.closeSubMenu();

}}

}

Page 19: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;

},mouseOut: function (e) {

if (this mouseout is important) {this.closeSubMenu();

}}

}Development time: about 10 minutes

Page 20: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;

},mouseOut: function (e) {

if (this mouseout is important) {this.closeSubMenu();

}}

}Development time: about 2 days

Page 21: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

How do we do this?

onmouseout, find out which element the mouse goes to.

If that element is not a part of the submenu, fold the submenu.

Page 22: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

How do we do this?

mouseOut: function (e) {e = e || window.event;var el = e.relatedTarget || e.toElement;if (!submenu.contains(el)) {

this.closeSubMenu();}

}

Page 23: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Find the element the mouse goes to.

mouseOut: function (e) {e = e || window.event;var el = e.relatedTarget || e.toElement;if (!submenu.contains(el)) {

this.closeSubMenu();}

}

Page 24: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Find the element the mouse goes to.

mouseOut: function (e) {e = e || window.event;var el = e.relatedTarget || e.toElement;if (!submenu.contains(el)) {

this.closeSubMenu();}

}

Page 25: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Find the element the mouse goes to.

mouseOut: function (e) {e = e || window.event;var el = e.relatedTarget || e.toElement;if (!submenu.contains(el)) {

this.closeSubMenu();}

}

Page 26: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

See whether that element is contained by the submenu.

mouseOut: function (e) {e = e || window.event;var el = e.relatedTarget || e.toElement;if (!submenu.contains(el)) {

this.closeSubMenu();}

}

Page 27: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

See whether that element is contained by the submenu.

mouseOut: function (e) {e = e || window.event;var el = e.relatedTarget || e.toElement;if (!submenu.contains(el)) {

this.closeSubMenu();}

}

Page 28: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

mouseOut: function (e) {e = e || window.event;var el = e.relatedTarget || e.toElement;if (!submenu.contains(el)) {

this.closeSubMenu();}

}

That's it, right?

<grin type=”evil” />

Page 29: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

Wrong!

Suppose someone doesn't use a mouse at all,

but the keyboard

how does the menu fold out?

Page 30: Voices That Matter: JavaScript Events

Deviceindependence

Page 31: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;

}}

Page 32: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;

}}

Doesn't work without a mouse.

Page 33: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;

}}

We need events that tell us whether the user enters or leaves a link.focus and blur

Page 34: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = dropdown.onfocus = this.mouseOver;

dropdown.onmouseout = dropdown.onblur = this.mouseOut;

}}

Page 35: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = dropdown.onfocus = this.mouseOver;

dropdown.onmouseout = dropdown.onblur = this.mouseOut;

}}

Doesn't work.

Page 36: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = dropdown.onfocus = this.mouseOver;

dropdown.onmouseout = dropdown.onblur = this.mouseOut;

}}

Focus and blur don't bubble.

Page 37: Voices That Matter: JavaScript Events

To bubble or not to bubble

Two kinds of events:1) Mouse and key events2) Interface events

Page 38: Voices That Matter: JavaScript Events

To bubble or not to bubble

Two kinds of events:1) Mouse and key events2) Interface events

Fire when the user initiates a device-specific action.mouseover, mouseout, click, keydown, keypress

Page 39: Voices That Matter: JavaScript Events

To bubble or not to bubble

Two kinds of events:1) Mouse and key events2) Interface events

In general they bubble

Page 40: Voices That Matter: JavaScript Events

To bubble or not to bubble

Two kinds of events:1) Mouse and key events2) Interface events

Fire when a certain event takes place, regardless of how it was initialised.load, change, submit, focus, blur

Page 41: Voices That Matter: JavaScript Events

To bubble or not to bubble

Two kinds of events:1) Mouse and key events2) Interface events

Generally don't bubble

Page 42: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;

}}

Page 43: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;var x = dropdown.getElementsByTagName('li');for (var i=0;i<x.length;i++) {

x[i].onfocus = this.mouseOver;x[i].onblur = this.mouseOut;

}}

}

Page 44: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;var x = dropdown.getElementsByTagName('li');for (var i=0;i<x.length;i++) {

x[i].onfocus = this.mouseOver;x[i].onblur = this.mouseOut;

}}

}Doesn't work.

Page 45: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

The HTML elements must be able to receive the keyboard focus.

- links- form fields

Page 46: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

The HTML elements must be able to receive the keyboard focus.

- links- form fields- elements with tabindex

Page 47: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;var x = dropdown.getElementsByTagName('li');for (var i=0;i<x.length;i++) {

x[i].onfocus = this.mouseOver;x[i].onblur = this.mouseOut;

}}

}

Page 48: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;var x = dropdown.getElementsByTagName('a');for (var i=0;i<x.length;i++) {

x[i].onfocus = this.mouseOver;x[i].onblur = this.mouseOut;

}}

}

Page 49: Voices That Matter: JavaScript Events

Dropdown menu <sigh />

var dropdown = {init: function (dropdown) {

dropdown.onmouseover = this.mouseOver;dropdown.onmouseout = this.mouseOut;var x = dropdown.getElementsByTagName('a');for (var i=0;i<x.length;i++) {

x[i].onfocus = this.mouseOver;x[i].onblur = this.mouseOut;

}}

}

Page 50: Voices That Matter: JavaScript Events

Event delegation

So we're stuck with setting a focus and blur event on every single link.

Or are we ... ?

In my recent Yahoo! presentation I give an outline of the solution.http://yuiblog.com/blog/2009/04/27/video-ppk-jsevents/

Page 51: Voices That Matter: JavaScript Events

More deviceindependence

Page 52: Voices That Matter: JavaScript Events

And what about click?

We're in luck: click also fires when the user activates an element by keyboard.

Restriction: the element must be able to receive the keyboard focus

Page 53: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-dropuses the mousemove event

Page 54: Voices That Matter: JavaScript Events

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 55: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-dropuses the mousemove event

How do we make this keyboard accessible?

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

Page 56: Voices That Matter: JavaScript Events

The key events

Page 57: Voices That Matter: JavaScript Events

keydownWhen a key is depressed.

Repeats.keypress

keyup

Page 58: Voices That Matter: JavaScript Events

keydownWhen a key is depressed.

Repeats.keypress

When a character key is depressed.

Repeats.keyup

Page 59: Voices That Matter: JavaScript Events

keydownWhen a key is depressed.

Repeats.keypress

When a character key is depressed.

Repeats.keyup

When a key is released.

Page 60: Voices That Matter: JavaScript Events

keydown and keypress

Page 61: Voices That Matter: JavaScript Events

keydown only

Page 62: Voices That Matter: JavaScript Events

Originally this theory was created by Microsoft.

Safari has copied it.

It's the only theory; Firefox and Opera just fire some random events.

Page 63: Voices That Matter: JavaScript Events

keydownWhen a key is depressed.

Repeats.keypress

When a character key is depressed. Repeats.

Page 64: Voices That Matter: JavaScript Events

Which key did my user press?

el.onkeydown = function (e) {e = e || window.event;var realKey = e.keyCode;

}

Page 65: Voices That Matter: JavaScript Events

Which key did my user press?

el.onkeydown = function (e) {e = e || window.event;var realKey = e.keyCode;

}

Page 66: Voices That Matter: JavaScript Events

Separate concepts

Back to the drag-and-drop

Page 67: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

We need the keydown event, because arrow keys are special keys.

Page 68: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

Page 69: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

Doesn't work.

Page 70: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

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

Page 71: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

obj.onmousemove = obj.onkeydown = moveElement;

The key events expect a keystroke.

Page 72: Voices That Matter: JavaScript Events

obj.onkeydown = function (e) {e = e || window.event;var key = e.keyCode;switch (key) {

case 37: // leftcase 38: // upcase 39: // rightcase 40: // down

return false;default:

return true;}

}

Page 73: Voices That Matter: JavaScript Events

Separate concepts

But what does “user hits right arrow once” mean?

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

Page 74: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

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

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

Page 75: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

Yes, that's more work.

But if you do it right you've got a generic drag and drop module you can use anywhere.

Page 76: Voices That Matter: JavaScript Events

Separate concepts

Drag-and-drop

Besides, I created a first draft for you.

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

Page 77: Voices That Matter: JavaScript Events
Page 78: Voices That Matter: JavaScript Events

change

Page 79: Voices That Matter: JavaScript Events

The change event fires when the value of a form field is changed.

This could be a very useful event; after all it fires only when the user actually changes somethinginstead of whenever he focuses on a form field

Page 80: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Page 81: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

focus

blur

No change event. The value hasn't been modified.

Page 82: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

focus

blur

Change event. The value has been modified.

Page 83: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Mouse:

Click on select

Page 84: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Mouse:

Click on new optionCHANGE

Page 85: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Keyboard:

focus

Focus on select

Page 86: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Keyboard:

focus arrow

Arrow keys to move to other optionCHANGE

Page 87: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Arrow keys to move to other optionCHANGE

This is a BUG!

Page 88: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Keyboard:

focus arrow

Arrow keys to move to other option

Page 89: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

Keyboard:

focus arrow blur

Blur select box.CHANGE

Page 90: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

click

CHANGE when the checked property changes.

Page 91: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

click

...

Page 92: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

click blur

CHANGE when the element loses the focus.

Page 93: Voices That Matter: JavaScript Events

- text fields- select boxes- checkboxes and radios

CHANGE when the element loses the focus.

This is a BUG!

Page 94: Voices That Matter: JavaScript Events

http://quirksmode.org/dom/events/

Page 95: Voices That Matter: JavaScript Events

Questions?

Ask away.

Or ask me on Twitterhttp://twitter.com/ppkor on my sitehttp://quirksmode.org