0
“It’s not you, It’s me”
How to avoid beingcoupled with a Javascript      framework.
Even if you loved it.Even if it was the right one.
Hello, who’s speaking?           Marco Cedaro             @cedmax
Hello, who’s speaking?           Marco Cedaro             @cedmax           About me...             Frontend Cowboy       ...
Hello, who’s speaking?           Marco Cedaro             @cedmax           About me...             Frontend Cowboy       ...
Hello, who’s speaking?           Marco Cedaro             @cedmax           About me...             Frontend Cowboy       ...
Hello, who’s speaking?           Marco Cedaro             @cedmax           Actually I am:            a Frontend Developer...
Hello, who’s speaking?           Marco Cedaro             @cedmax           Actually I am:            a Frontend Developer...
Hello, who’s speaking?           Marco Cedaro             @cedmax           Actually I am:            a Frontend Developer...
http://welovestyles.com/love-pictures/
http://everyoneneedsanalgonquin.com/2012/03/25/fruit-season/                        http://welovestyles.com/love-pictures/
General Purpose Frameworks                http://geekadelphia.com/2008/05/01/sick-ink-brah-alex-hillmans-geeky-love-hate-t...
LOVE FACT #1Love is a given, hatred is acquired.                            Doug Horton
Definitionframe·work n.A structure for supporting or enclosing somethingelse, especially a skeletal support used as the bas...
A little history            http://mattstone.blogs.com/photos/christian_art_genesis/adam-eve-and-the-tree.html
Once upon a timecode snippet  “dhtml”    if (document.all)                        http://creativecriminals.com/print/scotc...
Then
Then
Then
Then
Then
Now
Why did they get so popular?     DOM access      Cross browser implementation          Shorthands            Community sup...
Drawbacks
1. Community Support
Let’s Fight     http://www.rustybrick.com/prototype-js-vs-jquery-comparison.html -http://www.fotolog.com/alinolandia/36818...
Where’s your community now?             http://www.rustybrick.com/prototype-js-vs-jquery-comparison.html -http://www.fotol...
2. Updating is a mess
General purposeframework may seem the right solution to  handle complexity         Long life cycle websites               ...
General purposeframework may seem       New browser, new the right solution to   framework version  handle complexity     ...
General purpose                                                                                         How many patches d...
Counterintuitivelysituation is even worse         Short life cycle websites                          http://www.cnbc.com/i...
Counterintuitively     Less analysis andsituation is even worse       foresight         Short life cycle websites         ...
Did you make any   Counterintuitively     Less analysis and                                                               ...
Our job is evolving
Its the browser, baby
Its the browser, baby
Some frameworks are  just not built for   maintainability
Some frameworks are  just not built for      simplicity
Some frameworks are  just not built for        love
3. Code Portability
Own scripts built on a known framework                         case study                           http://www.naba.it/new...
Own scripts built on a    Brand new website known framework         with responsive design                         case st...
Own scripts built on a    Brand new website                                             same old bloat code known framewor...
Desktop$LAB   .script("jquery.js").wait()   .script("scripts.js");               Mobile$LAB   .script("xui.js").wait()   ....
Desktop$LAB   .script("jquery.js").wait()   .script("scripts.js");               Mobile$LAB   .script("xui.js").wait()   ....
Its the browser, baby
and the devices            http://www.newfangled.com/mobile_technology_and_web_enhanced_devices
and the devices            http://www.newfangled.com/mobile_technology_and_web_enhanced_devices
We need our code to be    PORTABLE
We need our code to be    PORTABLE        but how?
DISCLAIMER        http://www.destructoid.com/disappointment-a-postmortem-of-l-a-noire-224486.phtml
Go Vanilla  http://s394.photobucket.com/albums/pp28/cojohn55/?action=view&current=tasty-thursday-187-lets-get-naked.gif&me...
LOVE FACT #2What is known as a French Kiss in the English speaking world is called an        English Kiss in France.
Loops
$.each(items, function(i, item) {    [...]});Ext.each(items, function(item, i) {    [...]});_.each(items, function(item, i...
$.each(items, function(i, item) {    [...]});Ext.each(items, function(item, i) {    [...]});_.each(items, function(item, i...
$.each(items, function(i, item) {    [...]});Ext.each(items, function(item, i) {    [...]});_.each(items, function(item, i...
$.each(items, function(i, item) {    [...]});Ext.each(items, function(item, i) {    [...]});_.each(items, function(item, i...
$.each(items, function(i, item) {    [...]});
$.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++) {   [...]};
operations per second (higher is better)
yes, but...              http://www.funnyjunk.com/funny_pictures/3454040/Guess+what/
you should             http://www.behaviorgap.com/sketch/things-you-can-control/
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, item;item = items[++i];) {   [...]};for (var i = -1; ++i < items.length;) {   [...]};for (var i = 0; i < ...
for (var i = -1, item;item = items[++i];) {   [...]};for (var i = -1; ++i < items.length;) {   [...]};for (var i = 0; i < ...
for (var i = -1, item;item = items[++i];) {   [...]};for (var i = -1; ++i < items.length;) {   [...]};for (var i = 0; i < ...
for (var i = -1, item;item = items[++i];) {   [...]};var i = 0;while (i < items.length) {   [...]   i++;};for (var i = -1;...
for (var i = -1, item;item = items[++i];) {   [...]};var i = 0;while (i < items.length) {   [...]   i++;};for (var i = -1;...
for (var i = -1, item;item = items[++i];) {   [...]};var i = 0;while (i < items.length) {   [...]   i++;};for (var i = -1;...
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/
Zip It!          http://screenrant.com/austin-powers-4-2-ross-50006/
...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;
$.proxy(conf.clicked, conf);conf.clicked.createDelegate(conf);conf.clicked.bind(conf)conf.clicked.bind(conf)
$.proxy(conf.clicked, conf);conf.clicked.createDelegate(conf);conf.clicked.bind(conf)conf.clicked.bind(conf)
$.proxy(conf.clicked, conf);conf.clicked.createDelegate(conf);conf.clicked.bind(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 = function(func, context) {    return function() {        func.apply(context, arguments);    };}myElm.onclick = ...
AAAARGGGHHH        http://digitivity.org/1044/rss-kill-your-productivity-make-you-insane-waste-time
MyNS.bind = function(func, context) {       return function() {       return func.apply(context, arguments);   };}myElm.on...
MyNS.bind = function(func, context) {       $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
Design Patterns                  http://failblog.org/vote
Wrapper Pattern
MyNS.bind = function(func, context) {       $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
MyNS.bind = function(func, context) {       $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
MyNS.bind = function(func, context) {       $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
Wrapper Pattern             http://www.pinkblog.it/post/8396/comprare-i-preservativi-vi-imbarazza
sorry I should have said“NSFW” and, moreover...                http://clericalwhispers.blogspot.it/2010/09/popes-anti-cond...
sorry I should have said“NSFW” and, moreover...                http://clericalwhispers.blogspot.it/2010/09/popes-anti-cond...
var AwesomeEffect = function(id, config){    var default = {        delay: 0,        duration: 500,        transition: "ea...
var AwesomeEffect = function(id, config){    var default = {        delay: 0,        duration: 500,        transition: "ea...
var AwesomeEffect = function(id, config){    var default = {        delay: 0,        duration: 500,        transition: "ea...
var AwesomeEffect = function(id, config){    var default = {        delay: 0,        duration: 500,        transition: "ea...
var AwesomeEffect = function(id, config){    var default = {        delay: 0,        duration: 500,        transition: "ea...
var AwesomeEffect = function(id, config){    var default = {        delay: 0,        duration: 500,        transition: "ea...
$.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 $.extend(default, config);}var AwesomeEffect = function(id, config...
MyNS.extend = function(destination, source) {    return $.extend(default, config);}var AwesomeEffect = function(id, config...
MyNS.extend = function(destination, source) {    return Ext.apply(default, config);}var AwesomeEffect = function(id, confi...
MyNS.extend = function(destination, source) {    return _.extend(default, config);}var AwesomeEffect = function(id, config...
MyNS.extend = function(destination, source) {    return Object.extend(default, config);}var AwesomeEffect = function(id, c...
Wasn’t it bad to delegate?                 http://clericalwhispers.blogspot.it/2010/09/popes-anti-condom-message-is-sabota...
MyNS.extend = function(destination, source) {    return $.extend(default, config);}var AwesomeEffect = function(id, config...
MyNS.extend = function(destination, source) {    return $.extend(default, config);}var AwesomeEffect = function(id, config...
deeply into it
MyNS.Layer = function(content, config){    config = MyNS.extend({        overlayOpacity:0.6,        imageLoading: "/img/wa...
MyNS.Layer = function(content, config){    config = MyNS.extend({        overlayOpacity:0.6,        imageLoading: "/img/wa...
MyNS.Layer = function(content, config){    config = MyNS.extend({        overlayOpacity:0.6,        imageLoading: "/img/wa...
MyNS.Layer = function(content, config){    config = MyNS.extend({        overlayOpacity:0.6,        imageLoading: "/img/wa...
MyNS.Layer = function(content, config){    config = MyNS.extend({        overlayOpacity:0.6,        imageLoading: "/img/wa...
MyNS.Layer = function(content, config){    config = MyNS.extend({        opacity: true,        modal: true,    }, config);...
MyNS.Layer = function(content, config){    config = MyNS.extend({        opacity: true,        modal: true,    }, config);...
MyNS.Layer = function(content, config){    config = MyNS.extend({        opacity: true,        modal: true,    }, config);...
MyNS.Layer = function(content, config){    config = MyNS.extend({        opacity: true,        modal: true,    }, config);...
MyNS.Layer = function(content, config){    config = MyNS.extend({        opacity: true,        modal: true,    }, config);...
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(paylo...
MyNS.notify("error", {      msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){      MyNS.Layer(paylo...
MyNS.notify("error", {      msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){      MyNS.Layer(paylo...
MyNS.notify("error", {      msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){      MyNS.Layer(paylo...
MyNS.notify("error", {      msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){      MyNS.Layer(paylo...
MyNS.notify("error", {      msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){      MyNS.Layer(paylo...
MyNS.notify("error", {      msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){      MyNS.Layer(paylo...
MyNS.notify("error", {      msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){      MyNS.Layer(paylo...
AdvantagesMyNS.listen("error", function(payload){      MyNS.Layer(payload.msg);});
Advantages            Sem anticMyNS.listen("error", function(payload){      MyNS.Layer(payload.msg);});
Advantages            Sem anticMyNS.listen("error", function(payload){      MyNS.Layer(payload.msg);});               More...
AdvantagesUnpluggable
almost decoupled        http://thewellversed.com/2010/12/09/love-warranties-they-dont-make-them-like-they-used-to/broken-h...
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@verlok         @aureliari@sid05         @lucasalvini
cross site menu
Goalsmodify a single file to update menu  do not depend on website implementation    do not interfere with website implemen...
AJAX:MicroAjax0.4kB
AJAX:       DOM:MicroAjax   TinyDOM0.4kB       0.4kB
AJAX:       DOM:      DOMEvents:MicroAjax   TinyDOM   Vine0.4kB       0.4kB     0.8kB
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
AJAX:             DOM:               DOMEvents:MicroAjax         TinyDOM            Vine0.4kB             0.4kB           ...
microAjax("static/nav.html", function (res) {    $.prependBody(res);    vine.bind("ftf_xsite_sel", "change", function(e){ ...
microAjax("static/nav.html", function (res) {    $.prependBody(res);    vine.bind("ftf_xsite_sel", "change", function(e){ ...
FTF.ajax("static/nav.html", { success: function (res) {    FTF.dom.prependBody(res);    FTF.evt.bind("ftf_xsite", "change"...
FTF.ajax("static/nav.html", { success: function (res) {    FTF.dom.prependBody(res);    FTF.evt.bind("ftf_xsite", "change"...
Actually decoupled         http://thewellversed.com/2010/12/09/love-warranties-they-dont-make-them-like-they-used-to/broke...
Ain’t that bad                 http://locomente.blogspot.it/2012/02/single-unemployed.html
LOVE FACT #32 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-ben...
Do you really need it?
Work to decouple yourFOUNDATION CODE
Work to decouple yourFOUNDATION 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-161...
Build own architecture              http://www.alegriphotos.com/Cards_castle-lphoto-ce5fe99d397c7bf789b6b43d64bf5683.html
Improve javascript skills               http://edtechdigest.wordpress.com/2010/09/06/6-reasons-why-students-need-21st-cent...
Desktop$LAB   .script("jquery.js").wait()   .script("lightbox.jquery.js")   .script("layer.desktop.js")   .script("scripts...
the whole point is
BE A JAVASCRIPT    PERVERT
BE A JAVASCRIPT    PERVERT
BE A JAVASCRIPT    PERVERT   play with javascript
BE A JAVASCRIPT    PERVERT      play with javascriptdiscover your own project needs
BE A JAVASCRIPT    PERVERT      play with javascriptdiscover your own project needs
BE A JAVASCRIPT    PERVERT      play with javascriptdiscover your own project needs     let github be your playground
BE A JAVASCRIPT    PERVERT      play with javascriptdiscover your own project needs     let github be your playground     ...
BE A JAVASCRIPT    PERVERT      play with javascriptdiscover your own project needs     let github be your playground     ...
BE A JAVASCRIPT    PERVERT      play with javascriptdiscover your own project needs     let github be your playground     ...
know when to stop
♥ your framework       http://bit.ly/jsbanana             marco@fromthefront.it             http://cedmax.com             ...
Upcoming SlideShare
Loading in...5
×

FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javascript framework)

979

Published on

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

Published in: Technology, Design
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
979
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
12
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "FFWD.PRO - It's not you, It's me (or how to avoid being coupled with a Javascript framework)"

  1. 1. “It’s not you, It’s me”
  2. 2. How to avoid beingcoupled with a Javascript framework.
  3. 3. Even if you loved it.Even if it was the right one.
  4. 4. Hello, who’s speaking? Marco Cedaro @cedmax
  5. 5. Hello, who’s speaking? Marco Cedaro @cedmax About me... Frontend Cowboy Nicola Vitto Jr.
  6. 6. Hello, who’s speaking? Marco Cedaro @cedmax About me... Frontend Cowboy Nicola Vitto Jr. Javascript Pervert Roberto Felter
  7. 7. Hello, who’s speaking? Marco Cedaro @cedmax About me... Frontend Cowboy Nicola Vitto Jr. Javascript Pervert Roberto Felter Marco.. who? basically anyone else
  8. 8. Hello, who’s speaking? Marco Cedaro @cedmax Actually I am: a Frontend Developer at Spreaker.com
  9. 9. Hello, who’s speaking? Marco Cedaro @cedmax Actually I am: a Frontend Developer at Spreaker.com Conference organizer with From The Front
  10. 10. 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
  11. 11. http://welovestyles.com/love-pictures/
  12. 12. http://everyoneneedsanalgonquin.com/2012/03/25/fruit-season/ http://welovestyles.com/love-pictures/
  13. 13. General Purpose Frameworks http://geekadelphia.com/2008/05/01/sick-ink-brah-alex-hillmans-geeky-love-hate-tattoos/
  14. 14. LOVE FACT #1Love is a given, hatred is acquired. Doug Horton
  15. 15. Definitionframe·work n.A structure for supporting or enclosing somethingelse, especially a skeletal support used as the basis forsomething being constructed.gen·er·al-pur·pose adj.Designed for or suitable to more than one use;broadly useful.
  16. 16. A little history http://mattstone.blogs.com/photos/christian_art_genesis/adam-eve-and-the-tree.html
  17. 17. Once upon a timecode snippet “dhtml” if (document.all) http://creativecriminals.com/print/scotch-tape-beyond-strong/
  18. 18. Then
  19. 19. Then
  20. 20. Then
  21. 21. Then
  22. 22. Then
  23. 23. Now
  24. 24. Why did they get so popular? DOM access Cross browser implementation Shorthands Community support
  25. 25. Drawbacks
  26. 26. 1. Community Support
  27. 27. Let’s Fight http://www.rustybrick.com/prototype-js-vs-jquery-comparison.html -http://www.fotolog.com/alinolandia/36818888/
  28. 28. Where’s your community now? http://www.rustybrick.com/prototype-js-vs-jquery-comparison.html -http://www.fotolog.com/alinolandia/36818888/
  29. 29. 2. Updating is a mess
  30. 30. General purposeframework may seem the right solution to handle complexity Long life cycle websites 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
  31. 31. General purposeframework may seem New browser, new the right solution to framework version handle complexity Long life cycle websites 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
  32. 32. General purpose How many patches didframework may seem New browser, new you make in your the right solution to framework version framework over years? handle complexity Long life cycle websites 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
  33. 33. Counterintuitivelysituation is even worse Short life cycle websites http://www.cnbc.com/id/46994692/The_Worst_Jobs_for_2012 - http://indiatransportportal.com/india-transport-studies/
  34. 34. Counterintuitively Less analysis andsituation is even worse foresight Short life cycle websites http://www.cnbc.com/id/46994692/The_Worst_Jobs_for_2012 - http://indiatransportportal.com/india-transport-studies/
  35. 35. Did you make any Counterintuitively Less analysis and patch in yoursituation is even worse foresight framework over years? Short life cycle websites http://www.cnbc.com/id/46994692/The_Worst_Jobs_for_2012 - http://indiatransportportal.com/india-transport-studies/
  36. 36. Our job is evolving
  37. 37. Its the browser, baby
  38. 38. Its the browser, baby
  39. 39. Some frameworks are just not built for maintainability
  40. 40. Some frameworks are just not built for simplicity
  41. 41. Some frameworks are just not built for love
  42. 42. 3. Code Portability
  43. 43. Own scripts built on a known framework case study 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
  44. 44. Own scripts built on a Brand new website known framework with responsive design case study 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
  45. 45. Own scripts built on a Brand new website same old bloat code known framework with responsive design over 3g? case study 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
  46. 46. Desktop$LAB .script("jquery.js").wait() .script("scripts.js"); Mobile$LAB .script("xui.js").wait() .script("scripts.js");
  47. 47. Desktop$LAB .script("jquery.js").wait() .script("scripts.js"); Mobile$LAB .script("xui.js").wait() .script("scripts.js");
  48. 48. Its the browser, baby
  49. 49. and the devices http://www.newfangled.com/mobile_technology_and_web_enhanced_devices
  50. 50. and the devices http://www.newfangled.com/mobile_technology_and_web_enhanced_devices
  51. 51. We need our code to be PORTABLE
  52. 52. We need our code to be PORTABLE but how?
  53. 53. DISCLAIMER http://www.destructoid.com/disappointment-a-postmortem-of-l-a-noire-224486.phtml
  54. 54. Go Vanilla http://s394.photobucket.com/albums/pp28/cojohn55/?action=view&current=tasty-thursday-187-lets-get-naked.gif&mediafilter=images
  55. 55. LOVE FACT #2What is known as a French Kiss in the English speaking world is called an English Kiss in France.
  56. 56. Loops
  57. 57. $.each(items, function(i, item) { [...]});Ext.each(items, function(item, i) { [...]});_.each(items, function(item, i) { [...]});items.each(function(item, i) { [...]});
  58. 58. $.each(items, function(i, item) { [...]});Ext.each(items, function(item, i) { [...]});_.each(items, function(item, i) { [...]});items.each(function(item, i) { [...]});
  59. 59. $.each(items, function(i, item) { [...]});Ext.each(items, function(item, i) { [...]});_.each(items, function(item, i) { [...]});items.each(function(item, i) { [...]});
  60. 60. $.each(items, function(i, item) { [...]});Ext.each(items, function(item, i) { [...]});_.each(items, function(item, i) { [...]});items.each(function(item, i) { [...]});
  61. 61. $.each(items, function(i, item) { [...]});
  62. 62. $.each(items, function(i, item) { [...]});for (var i = 0; i < items.length; i++) { [...]};
  63. 63. $.each(items, function(i, item) { [...]});for (var i = 0; i < items.length; i++) { [...]};
  64. 64. operations per second (higher is better)
  65. 65. yes, but... http://www.funnyjunk.com/funny_pictures/3454040/Guess+what/
  66. 66. you should http://www.behaviorgap.com/sketch/things-you-can-control/
  67. 67. operations per second (higher is better)
  68. 68. operations per second (higher is better)
  69. 69. for (var i = 0; i < items.length; i++) { [...]};
  70. 70. for (var i = -1; ++i < items.length;) { [...]};for (var i = 0; i < items.length; i++) { [...]};
  71. 71. for (var i = -1; ++i < items.length;) { [...]};for (var i = 0; i < items.length; i++) { [...]};
  72. 72. for (var i = -1; ++i < items.length;) { [...]};for (var i = 0; i < items.length; i++) { [...]};
  73. 73. for (var i = -1, item;item = items[++i];) { [...]};for (var i = -1; ++i < items.length;) { [...]};for (var i = 0; i < items.length; i++) { [...]};
  74. 74. for (var i = -1, item;item = items[++i];) { [...]};for (var i = -1; ++i < items.length;) { [...]};for (var i = 0; i < items.length; i++) { [...]};
  75. 75. for (var i = -1, item;item = items[++i];) { [...]};for (var i = -1; ++i < items.length;) { [...]};for (var i = 0; i < items.length; i++) { [...]};
  76. 76. 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++) { [...]};
  77. 77. 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++) { [...]};
  78. 78. 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++) { [...]};//and counting -> http://jsperf.com/loops/33
  79. 79. Vanilla loop PROS Lots of flavors Performance benefits CONS mmm...
  80. 80. wait, what?too many characters?? http://screenrant.com/game-thrones-episode-7-recap-spoilers-benm-117660/
  81. 81. Zip It! http://screenrant.com/austin-powers-4-2-ross-50006/
  82. 82. ...and minify http://www.destentor.nl/algemeen/show/3347136/Minime-sleept-site-voor-rechter-om-sexvideo.ece
  83. 83. Yeah, baby, yeah http://www.destentor.nl/algemeen/show/3347136/Minime-sleept-site-voor-rechter-om-sexvideo.ece
  84. 84. Context Binding
  85. 85. var conf = { name: "jsDay", clicked: function(event) { alert(this.name); }}myElm.onclick = conf.clicked;
  86. 86. var conf = { name: "jsDay", clicked: function(event) { alert(this.name); }}myElm.onclick = conf.clicked;
  87. 87. var conf = { name: "jsDay", clicked: function(event) { alert(this.name); }}myElm.onclick = conf.clicked;
  88. 88. var conf = { name: "jsDay", clicked: function(event) { alert(this.name); }}myElm.onclick = conf.clicked;
  89. 89. var conf = { name: "jsDay", clicked: function(event) { alert(this.name); }}myElm.onclick = conf.clicked;
  90. 90. $.proxy(conf.clicked, conf);conf.clicked.createDelegate(conf);conf.clicked.bind(conf)conf.clicked.bind(conf)
  91. 91. $.proxy(conf.clicked, conf);conf.clicked.createDelegate(conf);conf.clicked.bind(conf)conf.clicked.bind(conf)
  92. 92. $.proxy(conf.clicked, conf);conf.clicked.createDelegate(conf);conf.clicked.bind(conf)conf.clicked.bind(conf)
  93. 93. myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);
  94. 94. myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);
  95. 95. myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);
  96. 96. myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);
  97. 97. myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);
  98. 98. myElm.onclick = (function(context){ return function(){ conf.clicked.apply(context, arguments); }})(conf);
  99. 99. argh, my eyes are bleeding.. http://www.accessexcellence.org/AE/mspot/tbs/episode3a/ep3a06.php
  100. 100. MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}
  101. 101. MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}
  102. 102. MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}
  103. 103. MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}
  104. 104. MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}
  105. 105. MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}myElm.onclick = MyNS.bind(conf.clicked, conf);
  106. 106. MyNS.bind = function(func, context) {    return function() {        func.apply(context, arguments);    };}myElm.onclick = MyNS.bind(conf.clicked, conf);myElm.onclick = $.proxy(conf.clicked, conf);
  107. 107. AAAARGGGHHH http://digitivity.org/1044/rss-kill-your-productivity-make-you-insane-waste-time
  108. 108. MyNS.bind = function(func, context) {     return function() {     return func.apply(context, arguments); };}myElm.onclick = MyNS.bind(conf.clicked, conf);
  109. 109. MyNS.bind = function(func, context) {     $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
  110. 110. Design Patterns http://failblog.org/vote
  111. 111. Wrapper Pattern
  112. 112. MyNS.bind = function(func, context) {     $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
  113. 113. MyNS.bind = function(func, context) {     $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
  114. 114. MyNS.bind = function(func, context) {     $.proxy(func, context);}myElm.onclick = MyNS.bind(conf.clicked, conf);
  115. 115. Wrapper Pattern http://www.pinkblog.it/post/8396/comprare-i-preservativi-vi-imbarazza
  116. 116. sorry I should have said“NSFW” and, moreover... http://clericalwhispers.blogspot.it/2010/09/popes-anti-condom-message-is-sabotage.html
  117. 117. sorry I should have said“NSFW” and, moreover... http://clericalwhispers.blogspot.it/2010/09/popes-anti-condom-message-is-sabotage.html
  118. 118. 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"};
  119. 119. 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"};
  120. 120. 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"};
  121. 121. 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"};
  122. 122. 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"};
  123. 123. 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"};
  124. 124. $.extend(default, config);Ext.apply(default, config);_.extend(default, config);Object.extend(default, config);
  125. 125. $.extend(default, config);Ext.apply(default, config);_.extend(default, config);Object.extend(default, config);
  126. 126. $.extend(default, config);Ext.apply(default, config);_.extend(default, config);Object.extend(default, config);
  127. 127. MyNS.extend = function(destination, source) { return $.extend(default, config);}var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}
  128. 128. MyNS.extend = function(destination, source) { return $.extend(default, config);}var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}
  129. 129. MyNS.extend = function(destination, source) { return Ext.apply(default, config);}var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}
  130. 130. MyNS.extend = function(destination, source) { return _.extend(default, config);}var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}
  131. 131. MyNS.extend = function(destination, source) { return Object.extend(default, config);}var AwesomeEffect = function(id, config){ var default = { delay: 0, duration: 500, transition: "easeOut", }; var options = MyNS.extend(default, config); [...]}
  132. 132. Wasn’t it bad to delegate? http://clericalwhispers.blogspot.it/2010/09/popes-anti-condom-message-is-sabotage.html
  133. 133. MyNS.extend = function(destination, source) { return $.extend(default, config);}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});
  134. 134. MyNS.extend = function(destination, source) { return $.extend(default, config);}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});
  135. 135. deeply into it
  136. 136. 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");
  137. 137. 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");
  138. 138. 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");
  139. 139. 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");
  140. 140. 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");
  141. 141. MyNS.Layer = function(content, config){ config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}MyNS.Layer("Sorry, an error occured");
  142. 142. MyNS.Layer = function(content, config){ config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}MyNS.Layer("Sorry, an error occured");
  143. 143. MyNS.Layer = function(content, config){ config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}MyNS.Layer("Sorry, an error occured");
  144. 144. MyNS.Layer = function(content, config){ config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}MyNS.Layer("Sorry, an error occured");
  145. 145. MyNS.Layer = function(content, config){ config = MyNS.extend({ opacity: true, modal: true, }, config); new FancyBox(content, config);}MyNS.Layer("Sorry, an error occured");
  146. 146. Event Driven Design
  147. 147. MyNS.Layer = function(content, config){ [...]}MyNS.Layer("Sorry, an error occured");
  148. 148. MyNS.Layer("Sorry, an error occured");
  149. 149. MyNS.notify("error", { msg: "Sorry, an error occured"});
  150. 150. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  151. 151. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  152. 152. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  153. 153. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  154. 154. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  155. 155. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  156. 156. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  157. 157. MyNS.notify("error", { msg: "Sorry, an error occured"});MyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  158. 158. AdvantagesMyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  159. 159. Advantages Sem anticMyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);});
  160. 160. Advantages Sem anticMyNS.listen("error", function(payload){ MyNS.Layer(payload.msg);}); More Flexible
  161. 161. AdvantagesUnpluggable
  162. 162. almost decoupled http://thewellversed.com/2010/12/09/love-warranties-they-dont-make-them-like-they-used-to/broken-heart/
  163. 163. What about ... ?
  164. 164. a real world example
  165. 165. DISCLAIMER #2 http://www.noncipossocredere.com/2012/04/26/lo-spam-arriva-soprattutto-dallindia/
  166. 166. From The Front
  167. 167. Not only the conference
  168. 168. basically a lot of stuff
  169. 169. basically a lot of stuff@verlok @aureliari@sid05 @lucasalvini
  170. 170. cross site menu
  171. 171. Goalsmodify a single file to update menu do not depend on website implementation do not interfere with website implementation
  172. 172. AJAX:MicroAjax0.4kB
  173. 173. AJAX: DOM:MicroAjax TinyDOM0.4kB 0.4kB
  174. 174. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kB
  175. 175. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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; } });});
  176. 176. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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; } });});
  177. 177. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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; } });});
  178. 178. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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; } });});
  179. 179. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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; } });});
  180. 180. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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; } });});
  181. 181. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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; } });});
  182. 182. AJAX: DOM: DOMEvents:MicroAjax TinyDOM Vine0.4kB 0.4kB 0.8kBOUR 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
  183. 183. 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; } });});
  184. 184. 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; } });});
  185. 185. 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; } });});
  186. 186. 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; } });});
  187. 187. Actually decoupled http://thewellversed.com/2010/12/09/love-warranties-they-dont-make-them-like-they-used-to/broken-heart/
  188. 188. Ain’t that bad http://locomente.blogspot.it/2012/02/single-unemployed.html
  189. 189. LOVE FACT #32 out of 5 people marry their first love.
  190. 190. You may want a silver bullet http://www.splattlog.com/2009/02/28/the-wolf-man-ecco-la-trasformazione-di-benicio-del-toro/
  191. 191. Do you really need it?
  192. 192. Work to decouple yourFOUNDATION CODE
  193. 193. Work to decouple yourFOUNDATION CODE AND TEST IT!
  194. 194. Let your UI rely on a framework http://loveallit.tumblr.com/post/1044567068/jegushi-please-dont-leave-me
  195. 195. Advantages of this approach
  196. 196. 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
  197. 197. Build own architecture http://www.alegriphotos.com/Cards_castle-lphoto-ce5fe99d397c7bf789b6b43d64bf5683.html
  198. 198. Improve javascript skills http://edtechdigest.wordpress.com/2010/09/06/6-reasons-why-students-need-21st-century-skills/
  199. 199. Desktop$LAB .script("jquery.js").wait() .script("lightbox.jquery.js") .script("layer.desktop.js") .script("scripts.js"); Mobile$LAB .script("xui.js").wait() .script("layer.mobile.js") .script("scripts.js")
  200. 200. the whole point is
  201. 201. BE A JAVASCRIPT PERVERT
  202. 202. BE A JAVASCRIPT PERVERT
  203. 203. BE A JAVASCRIPT PERVERT play with javascript
  204. 204. BE A JAVASCRIPT PERVERT play with javascriptdiscover your own project needs
  205. 205. BE A JAVASCRIPT PERVERT play with javascriptdiscover your own project needs
  206. 206. BE A JAVASCRIPT PERVERT play with javascriptdiscover your own project needs let github be your playground
  207. 207. BE A JAVASCRIPT PERVERT play with javascriptdiscover your own project needs let github be your playground javascript is fun
  208. 208. BE A JAVASCRIPT PERVERT play with javascriptdiscover your own project needs let github be your playground javascript is fun javascript is lovable
  209. 209. BE A JAVASCRIPT PERVERT play with javascriptdiscover your own project needs let github be your playground javascript is fun javascript is lovable but you also need to...
  210. 210. know when to stop
  211. 211. ♥ your framework http://bit.ly/jsbanana marco@fromthefront.it http://cedmax.com @cedmax
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×