ffwd.pro - it's not you, it's me (or how to avoid being coupled with a javascript...

Post on 29-Oct-2014

3 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

General purpose Javascript frameworks are the ones that made the language popular in the past, but right now it is a risk to think about our application development and architecture just in relation to our favorite framework.This talk highlights risks and suggest some techniques (from design patterns to snippet of code) to avoid being coupled to a specific framework

TRANSCRIPT

“It’s not you, It’s me”

How to avoid being coupled with a Javascript

framework.

Even if you loved it.

Even if it was the right one.

Hello, who’s speaking?

Marco Cedaro @cedmax

About me...

Frontend Cowboy Nicola Vitto Jr.

Hello, who’s speaking?

Marco Cedaro @cedmax

About me...

Frontend Cowboy Nicola Vitto Jr.

Javascript PervertRoberto Felter

Hello, who’s speaking?

Marco Cedaro @cedmax

About me...

Frontend Cowboy Nicola Vitto Jr.

Javascript PervertRoberto Felter

Marco.. who?basically anyone else

Hello, who’s speaking?

Marco Cedaro @cedmax

Actually I am:

a Frontend Developer at Spreaker.com

Hello, who’s speaking?

Marco Cedaro @cedmax

Actually I am:

a Frontend Developer at Spreaker.com

Conference organizer with From The Front

Hello, who’s speaking?

Marco Cedaro @cedmax

Actually I am:

a Frontend Developer at Spreaker.com

Conference organizer with From The Front

and a javascript pervert

Hello, who’s speaking?

Marco Cedaro @cedmax

http://welovestyles.com/love-pictures/http://everyoneneedsanalgonquin.com/2012/03/25/fruit-season/

General Purpose Frameworkshttp://geekadelphia.com/2008/05/01/sick-ink-brah-alex-hillmans-geeky-love-hate-tattoos/

LOVE FACT #1

Love is a given, hatred is acquired.Doug Horton

Definition

frame·work n.

A structure for supporting or enclosing something else, especially a skeletal support used as the basis for something being constructed.

gen·er·al-pur·pose adj.

Designed for or suitable to more than one use; broadly useful.

Once upon a time

code snippet

“dhtml”

if (document.all)

http://creativecriminals.com/print/scotch-tape-beyond-strong/

Then

Then

Then

Then

Then

Now

Why did they get so popular?

DOM access

Cross browser implementation

Shorthands

Community support

Drawbacks

1. Community Support

Let’s Fight

http://www.rustybrick.com/prototype-js-vs-jquery-comparison.html -http://www.fotolog.com/alinolandia/36818888/

http://www.rustybrick.com/prototype-js-vs-jquery-comparison.html -http://www.fotolog.com/alinolandia/36818888/

Where’s your community now?

2. Updating is a mess

Long life cycle websites

General purpose framework may seem the right solution to handle complexity

http://sproutsocial.com/insights/2011/11/how-to-iphone-ipad-friendly/ - http://pressganger.blogspot.it/2012/03/blog-progress-update.html - http://news.brothersoft.com/internet-explorer-10-focuses-html5-improves-performance-16036.html

Long life cycle websites

General purpose framework may seem the right solution to handle complexity

New browser, new framework version

http://sproutsocial.com/insights/2011/11/how-to-iphone-ipad-friendly/ - http://pressganger.blogspot.it/2012/03/blog-progress-update.html - http://news.brothersoft.com/internet-explorer-10-focuses-html5-improves-performance-16036.html

Long life cycle websites

General purpose framework may seem the right solution to handle complexity

New browser, new framework version

How many patches did you make in your

framework over years?

http://sproutsocial.com/insights/2011/11/how-to-iphone-ipad-friendly/ - http://pressganger.blogspot.it/2012/03/blog-progress-update.html - http://news.brothersoft.com/internet-explorer-10-focuses-html5-improves-performance-16036.html

Short life cycle websites

Counterintuitively situation is even worse

http://www.cnbc.com/id/46994692/The_Worst_Jobs_for_2012 - http://indiatransportportal.com/india-transport-studies/

Short life cycle websites

Counterintuitively situation is even worse

Less analysis and foresight

http://www.cnbc.com/id/46994692/The_Worst_Jobs_for_2012 - http://indiatransportportal.com/india-transport-studies/

Short life cycle websites

Counterintuitively situation is even worse

Less analysis and foresight

Did you make any patch in your

framework over years?

http://www.cnbc.com/id/46994692/The_Worst_Jobs_for_2012 - http://indiatransportportal.com/india-transport-studies/

Our job is evolving

It's the browser, baby

It's the browser, baby

Some frameworks are just not built formaintainability

Some frameworks are just not built for

simplicity

Some frameworks are just not built for

love

3. Code Portability

case study

Own scripts built on a known framework

Brand new website with responsive design

http://www.naba.it/newsletter_09_10/naba_n184.html - http://sevenspark.com/product/agility-responsive-minimal-html5-template/ - http://middleclasshell.com/republicans-ignore-catholics-when-it-comes-to-unemployment-benefits

case study

Own scripts built on a known framework

Brand new website with responsive design

same old bloat code over 3g?

http://www.naba.it/newsletter_09_10/naba_n184.html - http://sevenspark.com/product/agility-responsive-minimal-html5-template/ - http://middleclasshell.com/republicans-ignore-catholics-when-it-comes-to-unemployment-benefits

$LAB .script("jquery.js").wait() .script("scripts.js");

$LAB .script("xui.js").wait() .script("scripts.js");

Desktop

Mobile

$LAB .script("jquery.js").wait() .script("scripts.js");

$LAB .script("xui.js").wait() .script("scripts.js");

Desktop

Mobile

It's the browser, baby

and the deviceshttp://www.newfangled.com/mobile_technology_and_web_enhanced_devices

and the deviceshttp://www.newfangled.com/mobile_technology_and_web_enhanced_devices

We need our code to bePORTABLE

We need our code to bePORTABLE

but how?

DISCLAIMER

http://www.destructoid.com/disappointment-a-postmortem-of-l-a-noire-224486.phtml

Go Vanillahttp://s394.photobucket.com/albums/pp28/cojohn55/?action=view&current=tasty-thursday-187-lets-get-naked.gif&mediafilter=images

LOVE FACT #2

What is known as a French Kiss in the English speaking world is called an

English Kiss in France.

Loops

_.each(items, function(item, i) { [...]});

Ext.each(items, function(item, i) { [...]});

$.each(items, function(i, item) { [...]});

items.each(function(item, i) { [...]});

_.each(items, function(item, i) { [...]});

Ext.each(items, function(item, i) { [...]});

$.each(items, function(i, item) { [...]});

items.each(function(item, i) { [...]});

_.each(items, function(item, i) { [...]});

Ext.each(items, function(item, i) { [...]});

$.each(items, function(i, item) { [...]});

items.each(function(item, i) { [...]});

_.each(items, function(item, i) { [...]});

Ext.each(items, function(item, i) { [...]});

$.each(items, function(i, item) { [...]});

items.each(function(item, i) { [...]});

$.each(items, function(i, item) { [...]});

for (var i = 0; i < items.length; i++) { [...]};

$.each(items, function(i, item) { [...]});

for (var i = 0; i < items.length; i++) { [...]};

$.each(items, function(i, item) { [...]});

operations per second (higher is better)

operations per second (higher is better)

operations per second (higher is better)

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1, item;item = items[++i];) { [...]};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1, item;item = items[++i];) { [...]};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1, item;item = items[++i];) { [...]};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1, item;item = items[++i];) { [...]};

var i = 0;while (i < items.length) { [...] i++;};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1, item;item = items[++i];) { [...]};

var i = 0;while (i < items.length) { [...] i++;};

for (var i = -1; ++i < items.length;) { [...]};

for (var i = 0; i < items.length; i++) { [...]};

for (var i = -1, item;item = items[++i];) { [...]};

var i = 0;while (i < items.length) { [...] i++;};

//and counting -> http://jsperf.com/loops/33

Vanilla loop

PROS

Lots of flavors

Performance benefits

CONS

mmm...

wait, what?too many characters??

http://screenrant.com/game-thrones-episode-7-recap-spoilers-benm-117660/

...and minify

http://www.destentor.nl/algemeen/show/3347136/Minime-sleept-site-voor-rechter-om-sexvideo.ece

Yeah, baby, yeah

http://www.destentor.nl/algemeen/show/3347136/Minime-sleept-site-voor-rechter-om-sexvideo.ece

Context Binding

var conf = { name: "jsDay",

clicked: function(event) { alert(this.name); }}

myElm.onclick = conf.clicked;

var conf = { name: "jsDay",

clicked: function(event) { alert(this.name); }}

myElm.onclick = conf.clicked;

var conf = { name: "jsDay",

clicked: function(event) { alert(this.name); }}

myElm.onclick = conf.clicked;

var conf = { name: "jsDay",

clicked: function(event) { alert(this.name); }}

myElm.onclick = conf.clicked;

var conf = { name: "jsDay",

clicked: function(event) { alert(this.name); }}

myElm.onclick = conf.clicked;

conf.clicked.bind(conf)

conf.clicked.createDelegate(conf);

$.proxy(conf.clicked, conf);

conf.clicked.bind(conf)

conf.clicked.bind(conf)

conf.clicked.createDelegate(conf);

$.proxy(conf.clicked, conf);

conf.clicked.bind(conf)

conf.clicked.bind(conf)

conf.clicked.createDelegate(conf);

$.proxy(conf.clicked, conf);

conf.clicked.bind(conf)

myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);

myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);

myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);

myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);

myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);

myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);

argh, my eyes are bleeding..

http://www.accessexcellence.org/AE/mspot/tbs/episode3a/ep3a06.php

MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}

MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}

MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}

MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}

MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}

MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}

myElm.onclick = MyNS.bind(conf.clicked, conf);

MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}

myElm.onclick = $.proxy(conf.clicked, conf);

myElm.onclick = MyNS.bind(conf.clicked, conf);

AAAARGGGHHH

http://digitivity.org/1044/rss-kill-your-productivity-make-you-insane-waste-time

MyNS.bind = function(func, context) {    

}

myElm.onclick = MyNS.bind(conf.clicked, conf);

return function() {    return func.apply(context, arguments);};

MyNS.bind = function(func, context) {    

}

myElm.onclick = MyNS.bind(conf.clicked, conf);

$.proxy(func, context);

Design Patternshttp://failblog.org/vote

Wrapper Pattern

MyNS.bind = function(func, context) {    

}

myElm.onclick = MyNS.bind(conf.clicked, conf);

$.proxy(func, context);

MyNS.bind = function(func, context) {    

}

myElm.onclick = MyNS.bind(conf.clicked, conf);

$.proxy(func, context);

MyNS.bind = function(func, context) {    

}

myElm.onclick = MyNS.bind(conf.clicked, conf);

$.proxy(func, context);

http://www.pinkblog.it/post/8396/comprare-i-preservativi-vi-imbarazza

Wrapper Pattern

http://clericalwhispers.blogspot.it/2010/09/popes-anti-condom-message-is-sabotage.html

sorry I should have said“NSFW” and, moreover...

http://clericalwhispers.blogspot.it/2010/09/popes-anti-condom-message-is-sabotage.html

sorry I should have said“NSFW” and, moreover...

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

//{delay: 1000, duration:100, transition: "easeOut"};

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

//{delay: 1000, duration:100, transition: "easeOut"};

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

//{delay: 1000, duration:100, transition: "easeOut"};

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

//{delay: 1000, duration:100, transition: "easeOut"};

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

//{delay: 1000, duration:100, transition: "easeOut"};

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

//{delay: 1000, duration:100, transition: "easeOut"};

_.extend(default, config);

Ext.apply(default, config);

$.extend(default, config);

Object.extend(default, config);

_.extend(default, config);

Ext.apply(default, config);

$.extend(default, config);

Object.extend(default, config);

_.extend(default, config);

Ext.apply(default, config);

$.extend(default, config);

Object.extend(default, config);

MyNS.extend = function(destination, source) { return}

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}

$.extend(default, config);

MyNS.extend = function(destination, source) { return}

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}

$.extend(default, config);

MyNS.extend = function(destination, source) { return}

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}

Ext.apply(default, config);

MyNS.extend = function(destination, source) { return}

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}

_.extend(default, config);

MyNS.extend = function(destination, source) { return}

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}

Object.extend(default, config);

Wasn’t it bad to delegate?

http://clericalwhispers.blogspot.it/2010/09/popes-anti-condom-message-is-sabotage.html

MyNS.extend = function(destination, source) { return}

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

$.extend(default, config);

MyNS.extend = function(destination, source) { return}

var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}

var myEff = new AwesomeEffect("myId", { duration: 100, delay: 1000});

$.extend(default, config);

deeply into it

MyNS.Layer = function(content, config){

config = MyNS.extend({ overlayOpacity:0.6, imageLoading: "/img/warn.gif", }, config); new LightBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ overlayOpacity:0.6, imageLoading: "/img/warn.gif", }, config); new LightBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ overlayOpacity:0.6, imageLoading: "/img/warn.gif", }, config); new LightBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ overlayOpacity:0.6, imageLoading: "/img/warn.gif", }, config); new LightBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ overlayOpacity:0.6, imageLoading: "/img/warn.gif", }, config); new LightBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer = function(content, config){

config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}

MyNS.Layer("Sorry, an error occured");

Event Driven Design

MyNS.Layer = function(content, config){

[...]

}

MyNS.Layer("Sorry, an error occured");

MyNS.Layer("Sorry, an error occured");

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.notify("error", {

msg: "Sorry, an error occured"

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

Advantages

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

Advantages

Semantic

MyNS.listen("error", function(payload){

MyNS.Layer(payload.msg);

});

Advantages

Semantic

More Flexible

Advantages

Unpluggable

almost decoupled

http://thewellversed.com/2010/12/09/love-warranties-they-dont-make-them-like-they-used-to/broken-heart/

What about ... ?

a real world example

DISCLAIMER #2

http://www.noncipossocredere.com/2012/04/26/lo-spam-arriva-soprattutto-dallindia/

From The Front

Not only the conference

basically a lot of stuff

basically a lot of stuff

@sid05

@verlok @aureliari

@lucasalvini

cross site menu

Goals

modify a single file to update menu

do not depend on website implementation

do not interfere with website implementation

AJAX:MicroAjax0.4kB

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

AJAX:MicroAjax0.4kB

DOM: TinyDOM0.4kB

DOMEvents: Vine0.8kB

OUR CODE:microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

SIZE: 1.8kB

microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

microAjax("static/nav.html", function (res) { $.prependBody(res); vine.bind("ftf_xsite_sel", "change", function(e){ var s = $.id("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

FTF.ajax("static/nav.html", { success: function (res) { FTF.dom.prependBody(res); FTF.evt.bind("ftf_xsite", "change", function(e){ var s = FTF("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

FTF.ajax("static/nav.html", { success: function (res) { FTF.dom.prependBody(res); FTF.evt.bind("ftf_xsite", "change", function(e){ var s = FTF("ftf_xsite"); var href = s.options[s.selectedIndex].value; if (href) { document.location.href = href; } });});

Actually decoupled

http://thewellversed.com/2010/12/09/love-warranties-they-dont-make-them-like-they-used-to/broken-heart/

Ain’t that badhttp://locomente.blogspot.it/2012/02/single-unemployed.html

LOVE FACT #3

2 out of 5 people marry their first love.

You may want a silver bullet

http://www.splattlog.com/2009/02/28/the-wolf-man-ecco-la-trasformazione-di-benicio-del-toro/

Do you really need it?

Work to decouple your FOUNDATION CODE

Work to decouple your FOUNDATION CODE

AND TEST IT!

Let your UI rely on a framework

http://loveallit.tumblr.com/post/1044567068/jegushi-please-dont-leave-me

Advantages of this approach

Portability & Maintainability

http://news.tecnozoom.it/tv-lcd/piu-persone-usano-tv-ed-internet-contemporaneamente-post-16157.html - http://marine.rina.org/CATEGORIE_SERVIZI/Gestione_rischio/servizi/maintenance.aspx

Improve javascript skills

http://edtechdigest.wordpress.com/2010/09/06/6-reasons-why-students-need-21st-century-skills/

Mobile$LAB .script("xui.js").wait() .script("layer.mobile.js") .script("scripts.js")

$LAB .script("jquery.js").wait() .script("lightbox.jquery.js") .script("layer.desktop.js") .script("scripts.js");

Desktop

the whole point is

BE A JAVASCRIPT PERVERT

BE A JAVASCRIPT PERVERT

play with javascript

BE A JAVASCRIPT PERVERT

play with javascript

discover your own project needs

BE A JAVASCRIPT PERVERT

play with javascript

discover your own project needs

BE A JAVASCRIPT PERVERT

play with javascript

discover your own project needs

BE A JAVASCRIPT PERVERT

let github be your playground

play with javascript

discover your own project needs

BE A JAVASCRIPT PERVERT

let github be your playground

javascript is fun

play with javascript

discover your own project needs

BE A JAVASCRIPT PERVERT

let github be your playground

javascript is fun

javascript is lovable

play with javascript

discover your own project needs

BE A JAVASCRIPT PERVERT

let github be your playground

javascript is fun

javascript is lovablebut you also need to...

know when to stop

top related