YUI 3: Events Evolved

Post on 25-May-2015

4.354 views 2 download

Tags:

description

An overview of some of the features in YUI 3's event system. Presented at YUIConf 2009.

Transcript of YUI 3: Events Evolved

YUICONF 2009

yuilibrary: lsmith

github: lsmith

twitter: @ls_n

Luke Smith

Events Evolved

Monday, January 17, 2011

YUICONF 2009

<input type="button" onclick="doSomething();">

Monday, January 17, 2011

YUICONF 2009

<input type="button" onclick="doSomething();">

Monday, January 17, 2011

YUICONF 2009

<input type="button" onclick="doSomething();">

button.onclick = doSomething;

Monday, January 17, 2011

YUICONF 2009

button.onclick = doSomething;

<input type="button" onclick="doSomething();">

Monday, January 17, 2011

YUICONF 2009

button.onclick = doSomething;

<input type="button" onclick="doSomething();">

button.addEventListener('click', doSomething, false);

Monday, January 17, 2011

YUICONF 2009

button.addEventListener('click', doSomething, false);

<input type="button" onclick="doSomething();">

button.onclick = doSomething;

Monday, January 17, 2011

YUICONF 2009

button.addEventListener('click', doSomething, false);

<input type="button" onclick="doSomething();">

button.onclick = doSomething;

Monday, January 17, 2011

YUICONF 2009

if (button.addEventListener) { button.addEventListener('click', doSomething, false);} else if (button.attachEvent) { button.attachEvent('click', doSomething);} else { button.onclick = doSomething;}

Monday, January 17, 2011

YUICONF 2009

if (button.addEventListener) { button.addEventListener('click', doSomething, false);} else if (button.attachEvent) { button.attachEvent('click', doSomething);} else { button.onclick = doSomething;}

DUMB

Monday, January 17, 2011

YUICONF 2009

<input type="button" onclick="doSomething();">

button.onclick = doSomething;

button.addEventListener('click', doSomething, false);

if (button.addEventListener) { /* madness */ }

Monday, January 17, 2011

YUICONF 2009

if (button.addEventListener) { /* madness */ }

<input type="button" onclick="doSomething();">

button.onclick = doSomething;

button.addEventListener('click', doSomething, false);

addEvent(button, 'click', doSomething);

Monday, January 17, 2011

YUICONF 2009

function doSomething(e) { if (e && e.preventDefault) { e.preventDefault(); }

return false;}

Monday, January 17, 2011

YUICONF 2009

function doSomething(e) { if (e && e.preventDefault) { e.preventDefault(); }

return false;}

Monday, January 17, 2011

YUICONF 2009

We've been through this

function doSomething(e) { if (e && e.preventDefault) { e.preventDefault(); }

return false;}

Monday, January 17, 2011

YUICONF 2009

if (button.addEventListener) { /* madness */ }

<input type="button" onclick="doSomething();">

button.onclick = doSomething;

button.addEventListener('click', doSomething, false);

addEvent(button, 'click', doSomething);

Monday, January 17, 2011

YUICONF 2009

if (button.addEventListener) { /* madness */ }

<input type="button" onclick="doSomething();">

button.onclick = doSomething;

button.addEventListener('click', doSomething, false);

addEvent(button, 'click', doSomething);

Monday, January 17, 2011

YUICONF 2009

YAHOO.util.Event.on(button,'click',doSomething);

YUI 2

Monday, January 17, 2011

YUICONF 2009

YAHOO.util.Event.on(button,'click',doSomething);

YAHOO.util.Event.preventDefault(e);

YUI 2

Monday, January 17, 2011

YUICONF 2009

YAHOO.util.Event.on(button,'click',doSomething);

YAHOO.util.Event.preventDefault(e);

YUI 2

✓Normalized subscription

Monday, January 17, 2011

YUICONF 2009

YAHOO.util.Event.on(button,'click',doSomething);

YAHOO.util.Event.preventDefault(e);

YUI 2

✓Normalized subscription✓Normalized event handling

Monday, January 17, 2011

YUICONF 2009

YAHOO.util.Event.on(button,'click',doSomething);

YAHOO.util.Event.preventDefault(e);

YUI 2

✓Normalized subscription✓Normalized event handling✓DOM-like method names

Monday, January 17, 2011

YUICONF 2009

button.on('click', doSomething);

e.preventDefault();

YUI 3

Monday, January 17, 2011

YUICONF 2009

button.on('click', doSomething);

e.preventDefault();

YUI 3

✓Normalized subscription

Monday, January 17, 2011

YUICONF 2009

button.on('click', doSomething);

e.preventDefault();

YUI 3

✓Normalized subscription✓Normalized event handling

Monday, January 17, 2011

YUICONF 2009

button.on('click', doSomething);

e.preventDefault();

YUI 3

✓Normalized subscription✓Normalized event handling✓DOM-like method names

Monday, January 17, 2011

YUICONF 2009

button.on('click', doSomething);

e.preventDefault();

YUI 3

✓Normalized subscription✓Normalized event handling✓DOM-like method names✓DOM-like context

Monday, January 17, 2011

YUICONF 2009

button.on('click', doSomething);

e.preventDefault();

YUI 3

✓Normalized subscription✓Normalized event handling✓DOM-like method names✓DOM-like context✓Terse

Monday, January 17, 2011

YUICONF 2009

We give you the DOM

Monday, January 17, 2011

YUICONF 2009

We give you the DOM

... but it works

Monday, January 17, 2011

YUICONF 2009

You are here

Monday, January 17, 2011

YUICONF 2009

Custom Events

YUI 2

Monday, January 17, 2011

YUICONF 2009

this.myEvent = new YAHOO.util.CustomEvent("myEvent");

Custom Events

instance.myEvent.subscribe(doSomething);

YUI 2

this.myEvent.fire();

Monday, January 17, 2011

YUICONF 2009

Custom Events

YUI 2

instance.subscribe("myEvent",doSomething);

this.fireEvent("myEvent");

Monday, January 17, 2011

YUICONF 2009

Custom Events

instance.on("myEvent", doSomething);

YUI 3

this.fire("myEvent");

Monday, January 17, 2011

YUICONF 2009

this.publish("myEvent", config);

Custom Events

instance.on("myEvent", doSomething);

YUI 3

this.fire("myEvent");

Monday, January 17, 2011

YUICONF 2009

Y.extend( MyClass, Y.EventTarget );

Y.EventTarget

✓ Event API

Monday, January 17, 2011

YUICONF 2009

Y.extend( MyClass, Y.Base );

Y.EventTarget

✓ Event API

Y.Base

✓ Event API

✓ Attributes

✓ Plugins

Monday, January 17, 2011

YUICONF 2009

Y.extend( MyClass, Y.Widget );

Y.EventTarget

✓ Event API

Y.Base

✓ Event API

✓ Attributes

✓ Plugins

Y.Widget

✓ Event API

✓ Attributes

✓ Plugins

✓ UI Lifecycle

Monday, January 17, 2011

YUICONF 2009

Y.extend( MyClass, Y.Widget );

Y.EventTarget

✓ Event API

Y.Base

✓ Event API

✓ Attributes

✓ Plugins

Y.Widget

✓ Event API

✓ Attributes

✓ Plugins

✓ UI Lifecycle

Monday, January 17, 2011

YUICONF 2009

Y.extend( MyClass, Y.Base );

Y.EventTarget

✓ Event API

Y.Base

✓ Event API

✓ Attributes

✓ Plugins

Y.Widget

✓ Event API

✓ Attributes

✓ Plugins

✓ UI Lifecycle

Monday, January 17, 2011

YUICONF 2009

✓DOM events

✓Custom events

Normalized subscription

instance.on("myEvent", doSomething);

button.on("click", doSomething);

Monday, January 17, 2011

YUICONF 2009

✓DOM events

✓Custom events

subscriptionUnified

instance.on("myEvent", doSomething);

button.on("click", doSomething);

Monday, January 17, 2011

YUICONF 2009

DOM Events Module/App Events

Event API

Your App

Monday, January 17, 2011

YUICONF 2009

DOMCustom Events

Monday, January 17, 2011

YUICONF 2009

DOMCustom Events

Monday, January 17, 2011

YUICONF 2009

Custom Events more DOM like

✓Unify Subscription API

- Default behaviors

- Bubbling

Monday, January 17, 2011

YUICONF 2009

Custom Events more DOM like

✓Unify Subscription API

- Default behaviors

- Bubbling

foo.on(event, fn)

Monday, January 17, 2011

YUICONF 2009

Custom Events more DOM like

✓Unify Subscription API

- Default behaviors

- Bubblingthis.publish(...)

Monday, January 17, 2011

YUICONF 2009

Custom Events more DOM like

Default behaviors

Monday, January 17, 2011

YUICONF 2009

this.publish("myEvent", config);

Custom Events

YUI 3

instance.on("myEvent", doSomething);

this.fire("myEvent");

Monday, January 17, 2011

YUICONF 2009

this.publish("myEvent", config);

Custom Events

YUI 3

Monday, January 17, 2011

YUICONF 2009

initializer: function () {

this.publish("start", {

defaultFn: this._defStartFn

});

}

Default behaviors

this.publish( name, config );

Monday, January 17, 2011

YUICONF 2009

initializer: function () {

this.publish("start", {

defaultFn: this._defStartFn

});

}

Default behaviors

this.publish( name, config );

Monday, January 17, 2011

YUICONF 2009

Default behaviors

initializer: function () { ... },

_defStartFn: function (e) {

Y.log("started " + e.time);

this._disableControls();

this._getGoing(e.urgency);}

Monday, January 17, 2011

YUICONF 2009

e.timee.urgency

this.fire("start", payload);

Event payload

Monday, January 17, 2011

YUICONF 2009

e.timee.urgency

Event payload

this.fire("start", { time: new Date(), urgency: 'ASAP'});

Monday, January 17, 2011

YUICONF 2009

instance.on("start", doSomething);

this.fire("start");

Monday, January 17, 2011

YUICONF 2009

instance.on("start", doSomething);

this.fire("start"); execute subscribers

_defStartFn

prevented?end yes

no

Monday, January 17, 2011

YUICONF 2009

function doSomething(e) {

if (e.urgency === 'ASAP') {

e.preventDefault();

}

}

Behavior is preventableprevented?

Monday, January 17, 2011

YUICONF 2009

... but it doesn't have to be

initializer: function () {

this.publish("start", {

defaultFn: this._defStartFn,

preventable: false

});

}

Monday, January 17, 2011

YUICONF 2009

... but it doesn't have to be

initializer: function () {

this.publish("start", {

defaultFn: this._defStartFn,

preventedFn: this._prvStartFn

});

}

Monday, January 17, 2011

YUICONF 2009

Monday, January 17, 2011

YUICONF 2009

Dogfood (nom)

initializer: function () { this.publish("add", { defaultFn: this._defAddFn });

this.publish("flush", { defaultFn: this._defFlushFn });}

cache.js

Monday, January 17, 2011

YUICONF 2009

Dogfood (nom)

initializer: function () { this.publish(ENTRY, { defaultFn: this._defEntryFn });

this.publish(RESET, { defaultFn: this._defResetFn });}

console.js

Monday, January 17, 2011

YUICONF 2009

Dogfood (nom)

initializer: function () { this.publish("request", { defaultFn: Y.bind("_defRequestFn", this), queuable:true }); ...}

datasource.js

Monday, January 17, 2011

YUICONF 2009

Dogfood (nom)

initializer: function () { this.publish(EV_MOUSE_DOWN, { defaultFn: this._defMouseDownFn, bubbles: true }); ...}

drag.js

Monday, January 17, 2011

YUICONF 2009

Dogfood (nom)

initializer: function () { this.publish(SYNC, { defaultFn: this._defSyncFn }); this.publish(POSITION_THUMB, { defaultFn: this._defPositionThumbFn });}

slider.js

Monday, January 17, 2011

YUICONF 2009

Dogfood (nom)

this.publish({

execute: { defaultFn : this._defExecFn },

shift : { defaultFn : this._defShiftFn },

add : { defaultFn : this._defAddFn },

promote: { defaultFn : this._defPromoteFn },

remove : { defaultFn : this._defRemoveFn }

});

async-queue.js

Monday, January 17, 2011

YUICONF 2009

We love default behaviors

You should, too

Monday, January 17, 2011

YUICONF 2009

Custom Events more DOM like

✓Unify Subscription API

✓Default behaviors

- Bubbling

Monday, January 17, 2011

YUICONF 2009

Custom Events more DOM like

Bubbling

Monday, January 17, 2011

YUICONF 2009

Bubbling

initializer: function () {

this.publish("start", {

bubbles: true

});

this.addTarget(host);

}

Monday, January 17, 2011

YUICONF 2009

Bubbling

initializer: function () {

this.publish("start", {

broadcast: 1

});

}

Monday, January 17, 2011

YUICONF 2009

Bubbling

initializer: function () {

this.publish("start", {

bubbles: true,

stoppedFn: this._stopStartFn

});

}

Monday, January 17, 2011

YUICONF 2009

Event Delegation

<UL>

<li>one</li>

<li>two</li>

<li>three</li>

<li>four</li>

<li>five</li>

<li>six</li>

Y.all('li') .on('click', sayHi);

Monday, January 17, 2011

YUICONF 2009

Event Delegation

<UL>

<li>one</li>

<li>two</li>

<li>three</li>

<li>four</li>

<li>five</li>

<li>six</li>

Y.all('li') .on('click', sayHi);

6 subscriptions

Monday, January 17, 2011

YUICONF 2009

Event Delegation

Y.one('ul') .on('click', sayHi);

<UL>

<li>one</li>

<li>two</li>

<li>three</li>

<li>four</li>

<li>five</li>

<li>six</li>

Monday, January 17, 2011

YUICONF 2009

Event Delegation

Y.one('ul') .on('click', sayHi);

1 subscription

<UL>

<li>one</li>

<li>two</li>

<li>three</li>

<li>four</li>

<li>five</li>

<li>six</li>

Monday, January 17, 2011

YUICONF 2009

Event Delegation

Y.one('ul').delegate( 'click',sayHi,'li');

<UL>

<li>one</li>

<li>two</li>

<li>three</li>

<li>four</li>

<li>five</li>

<li>six</li>

Monday, January 17, 2011

YUICONF 2009

Event Delegation

Y.one('ul').delegate( 'click',sayHi,'li');

1 subscription

<UL>

<li>one</li>

<li>two</li>

<li>three</li>

<li>four</li>

<li>five</li>

<li>six</li>

Monday, January 17, 2011

YUICONF 2009

Event Delegation

instance1

instance2

instance3

instance4

instance5

instance6

instance1.on('start', sayHi);

instance2.on('start', sayHi);

instance3.on('start', sayHi);

instance4.on('start', sayHi);

instance5.on('start', sayHi);

instance6.on('start', sayHi);

Monday, January 17, 2011

YUICONF 2009

Event Delegation

instance1

instance2

instance3

instance4

instance5

instance6

instance1.on('start', sayHi);

instance2.on('start', sayHi);

instance3.on('start', sayHi);

instance4.on('start', sayHi);

instance5.on('start', sayHi);

instance6.on('start', sayHi);

6 subscriptions

Monday, January 17, 2011

YUICONF 2009

Event Delegation

ManagerClass

instance1

instance2

instance3

instance4

instance5

instance6

Mgr.on('foo:start', sayHi);

Monday, January 17, 2011

YUICONF 2009

Event Delegation

ManagerClass

instance1

instance2

instance3

instance4

instance5

instance6

Mgr.on('foo:start', sayHi);

1 subscription

Monday, January 17, 2011

YUICONF 2009

Event Delegation

ManagerClass

instance1

instance2

instance3

instance4

instance5

instance6

Mgr.on('foo:start', sayHi);

1 subscription

initializer: function () { this.addTarget( this.get("host"); );}

Monday, January 17, 2011

YUICONF 2009

Dogfood

var draggable = new Y.DD.Drag({ node: '#dragme'});

draggable.on('start', doSomething);

Drag and Drop

Monday, January 17, 2011

YUICONF 2009

Dogfood

var draggable = new Y.DD.Drag({ node: '#dragme'});

Y.DD.DDM.on('drag:start', doSomething);

Drag and Drop

Monday, January 17, 2011

YUICONF 2009

Dogfood

Y.on('yui:log', doSomething);

Y.Global.on('yui:log', doSomething);

Y.Global

Monday, January 17, 2011

YUICONF 2009

Custom Events more DOM like

✓Unify Subscription API

✓Default behaviors

✓Bubbling

Monday, January 17, 2011

YUICONF 2009

DOMCustom Events

Monday, January 17, 2011

YUICONF 2009

Above and beyond

Monday, January 17, 2011

YUICONF 2009

Above and beyond

- Subscription context override

Monday, January 17, 2011

YUICONF 2009

Above and beyond

- Subscription context override

- Subscription payload

Monday, January 17, 2011

YUICONF 2009

Above and beyond

- Subscription context override

- Subscription payload

- Easy event detach

Monday, January 17, 2011

YUICONF 2009

Above and beyond

- Subscription context override

- Subscription payload

- Easy event detach

- "After" subscriptions

Monday, January 17, 2011

YUICONF 2009

Above and beyond

- Subscription context override

- Subscription payload

- Easy event detach

- "After" subscriptions

- New DOM events

Monday, January 17, 2011

YUICONF 2009

instance.on("start", myObj.startHandler);

on()++

Monday, January 17, 2011

YUICONF 2009

on()++

instance.on("start", Y.bind(myObj.startHandler, myObj));

Monday, January 17, 2011

YUICONF 2009

on()++

instance.on("start", myObj.startHandler, myObj);

instance.on(event, handler, context);

Monday, January 17, 2011

YUICONF 2009

on()++

node.on("click", myObj.clickHandler, myObj);

instance.on(event, handler, context);node.on(event, handler, context);

Monday, January 17, 2011

YUICONF 2009

instance.on("start", myObj.startHandler);

on()++

Monday, January 17, 2011

YUICONF 2009

on()++

instance.on("start", Y.rbind(myObj.startHandler, myObj, 1, new Date(), { foo: "bar" }));

Monday, January 17, 2011

YUICONF 2009

on()++

instance.on("start", myObj.startHandler, myObj, 1, new Date(), { foo: "bar" });

instance.on(evt, fn, ctx, arg1, ...argN);node.on(evt, fn, ctx, arg1, ...argN);

Monday, January 17, 2011

YUICONF 2009

on()++

instance.on("start", myObj.startHandler, myObj, 1, new Date(), { foo: "bar" });

instance.on(evt, fn, ctx, arg1, ...argN);node.on(evt, fn, ctx, arg1, ...argN);

node.on(evt, fn, null, arg1, ...argN);

Monday, January 17, 2011

YUICONF 2009

Above and beyond

✓Subscription context override

✓Subscription payload

- Easy event detach

- "After" subscriptions

- New DOM events

Monday, January 17, 2011

YUICONF 2009

Above and beyond

✓Subscription context override

✓Subscription payload

- Easy event detach

- "After" subscriptions

- New DOM events

Monday, January 17, 2011

YUICONF 2009

button.detach("click", doSomething);

Handles and categories

Monday, January 17, 2011

YUICONF 2009

button.detach("click", doSomething);

Handles and categories

var sub = button.on("click", doSomething);sub.detach();

Monday, January 17, 2011

YUICONF 2009

button.detach("click", doSomething);

Handles and categories

var sub = button.on("click", doSomething);sub.detach();

button.on("my-cat|click", doSomething);button.detach("my-cat|click");

Monday, January 17, 2011

YUICONF 2009

button.detach("click", doSomething);

Handles and categories

var sub = button.on("click", doSomething);sub.detach();

widget.on("guid|xChange", handleXChange);widget.on("guid|yChange", handleYChange);widget.detach("guid|*");

Monday, January 17, 2011

YUICONF 2009

Above and beyond

✓Subscription context override

✓Subscription payload

✓Easy event detach

- "After" subscriptions

- New DOM events

Monday, January 17, 2011

YUICONF 2009

Above and beyond

✓Subscription context override

✓Subscription payload

✓Easy event detach

- "After" subscriptions

- New DOM events

Monday, January 17, 2011

YUICONF 2009

instance

event

_defEventFn

instance.on(event,handler)

Monday, January 17, 2011

YUICONF 2009

instance

event

_defEventFn

instance.on(event,handler)

instance.after(event,handler)

Monday, January 17, 2011

YUICONF 2009

this.after("attrChange", this._updateUI);

After moments

Y.Base

✓ Event API

✓ Attributes

✓ Plugins

Monday, January 17, 2011

YUICONF 2009

this.after("attrChange", this._updateUI);

After moments

Side effects of a state change

Y.Base

✓ Event API

✓ Attributes

✓ Plugins

Monday, January 17, 2011

YUICONF 2009

instance

event

_defEventFn

instance.on(event,handler)

instance.after(event,handler)

Monday, January 17, 2011

YUICONF 2009

instance

event

_defEventFn

instance.on(event,handler)

instance.after(event,handler)

State UNCHANGED

Monday, January 17, 2011

YUICONF 2009

instance

event

_defEventFn

instance.on(event,handler)

instance.after(event,handler)

State UNCHANGED

Change state

Monday, January 17, 2011

YUICONF 2009

instance

event

_defEventFn

instance.on(event,handler)

instance.after(event,handler)

State UNCHANGED

Change state

State CHANGED

Monday, January 17, 2011

YUICONF 2009

Monday, January 17, 2011

YUICONF 2009

Above and beyond

✓Subscription context override

✓Subscription payload

✓Easy event detach

✓ "After" subscriptions

- New DOM events

Monday, January 17, 2011

YUICONF 2009

Above and beyond

✓Subscription context override

✓Subscription payload

✓Easy event detach

✓ "After" subscriptions

- New DOM events

Monday, January 17, 2011

YUICONF 2009

Y.Env.evt.plugins.YOUR_EVENT =Y.Node.DOM_EVENTS.YOUR_EVENT = {

on: function (type, handler, ctx) {

}

}

DOM++

Monday, January 17, 2011

YUICONF 2009

Y.Env.evt.plugins.YOUR_EVENT =Y.Node.DOM_EVENTS.YOUR_EVENT = {

on: function (type, handler, ctx) {

}

}

DOM++

Monday, January 17, 2011

YUICONF 2009

Y.Env.evt.plugins.konami =Y.Node.DOM_EVENTS.konami = {

}

Konami

Monday, January 17, 2011

YUICONF 2009

Y.Env.evt.plugins.konami =Y.Node.DOM_EVENTS.konami = { on: function (type, fn, ctx) { var progress = {}, handlers = {}, keys = [38,38,40,40,37,39,37,39,66,65], ... node.on("keydown", _checkProgress);

return detachHandle;}

Konami

Monday, January 17, 2011

YUICONF 2009

node.on('konami', addUnicorns);

Using your event

Monday, January 17, 2011

YUICONF 2009

Above and beyond

✓Subscription context override

✓Subscription payload

✓Easy event detach

✓ "After" subscriptions

✓New DOM events

Monday, January 17, 2011

YUICONF 2009

Summary✓Unified subscription

✓Default behaviors

✓Bubbling

✓Context override

✓Subscription payload

✓Easy event detach

✓ "After" subscriptions

✓New DOM events

DOMCustom Events

Monday, January 17, 2011

YUICONF 2009

Rethink how you use events

Monday, January 17, 2011

YUICONF 2009

Rethink how you build your apps

Monday, January 17, 2011