SlideShare uma empresa Scribd logo
1 de 35
http://www.flickr.com/photos/mocambique/511151694/




Building Large
jQuery Applications
Rebecca Murphey
Me

independent JavaScript developer
based in Durham, N.C.
contributor to O’Reilly’s jQuery Cookbook
co-host of the yayQuery podcast
code organization fanatic
What counts as
a large application?




http://www.flickr.com/photos/hippie/2475855465/
distinct but related pieces of functionality
extensive server communication
frequent updating of the page without reload
jQuery out of the box doesn’t give us
many tools for developing large applications;
its essentially a DOM manipulation and
Ajax library.
at doesn’t stop people from building
large applications with jQuery.
$(document).ready(function() {
    $('#myFeature li')
        .append('<div/>')
        .click(function() {
            var $this = $(this);
            var $div = $this.find('div');
            $div.load('foo.php?item=' +
                $this.attr('id'),
                function() {
                    $div.show();
                    $this.siblings()
                        .find('div').hide();
                }
            );
        })
});
// NAVIGATION
function togglePage(section) {
    // if the clicked section is already the current section AND we're in full page mode
    // minimize the current tab
    if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + '
a').hasClass('md_fullpage')) {
        // alert('clicked section is current section AND fullpage mode is active; teaser should
load');
    // Minimize
        jQuery('#md_tabs_navigation a').removeClass('md_fullpage');
        jQuery('.md_body').hide();
        jQuery('#md_feature').slideDown('normal',function(){
             var bodyContent = jQuery('#md_body_'+ section);
             bodyContent.fadeOut('normal',function(){
                 jQuery('#md_tabs_navigation a').each(function(){
                     var thisSection = jQuery(this).html().replace('<span<','').replace('</
span<','');
                     var thisSection_comp = thisSection.toLowerCase().replace(' ','_');
                     jQuery('#md_body_'+ thisSection_comp).load(
                         '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp,
                         function(){
                             tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body
input.thickbox');
                             bodyContent.animate({ height: 'toggle', opacity:
'toggle' },"slow");
                         }
                     );
                 });
             });
        });
        jQuery('#expandtabs span').empty().append('Expand Tabs');
    } else {
    // if the clicked section is NOT the current section OR we're NOT in full page mode
    // then let's go to full page mode and show the whole tab
How do you write an application that uses
jQuery without making a tangled mess?
e key is to think of our applications as small
pieces of functionality, and then write our code
accordingly.
Patterns & Practices

                  http://www.flickr.com/photos/docman/3270589892/
Above all else: Use jQuery as the DOM and Ajax
tool it is, not as a framework.
Use classes to organize your code; write
methods that do exactly one thing.
myApp.common.Messaging = Class.extend({
    animDuration : 500,
    hideDelay : 1500,

      init : function() {
          this.el = $('<div class="message"/>').prependTo('body').hide();
          $.subscribe('/message/notification', $.proxy(this._showMessage, this));
      },

      _showMessage : function(msg) {
          var hide = $.proxy(this._hideMessage, this);

           this.el.append('<p>' + msg + '</p>');

           if (!this.el.is(':visible')) {
               this.el.slideDown(this.animDuration, $.proxy(function() {
                    this.showTimeout = setTimeout(hide, this.hideDelay);
               }, this));
           } else {
               clearTimeout(this.showTimeout);
               this.showTimeout = setTimeout(hide, this.hideDelay);
           }
      },

      _hideMessage : function() {
          this.el.slideUp(this.animDuration);
          this._cleanup();
      },

      _cleanup : function() {
          this.el.empty();
      }
});
Use the server to send data, not markup; use a
templating system (like mustache.js) to create
markup on the client side.
myApp.widgets.Tools = Class.extend({
    itemTemplate : '<li>' +
        '<input type="checkbox" name="{{description}}" checked>' +
        '<label for="{{description}}">{{description}}</label>' +
    '</li>',

      services : [],

      init : function(el) {
          this.el = el;
          this.el.delegate('input', 'click', $.proxy(this._handleChoice, this));

           $.subscribe('/service/add', $.proxy(this._handleAdd, this));
      },

      _handleChoice : function(e) {
          var input = $(e.target),
              service = input.attr('name');

           $.publish('/service/' + service + '/toggle', [ input.is(':checked') ]);
      },

      _handleAdd : function(service) {
          if ($.inArray(service, this.services) >= 0) { return; }

           var html = Mustache.to_html(this.itemTemplate, { description : service });
           this.el.append(html);
      }
});
Use a consistent pattern for de ning
components that have a DOM representation.
var DomThinger = Class.extend({
    config : {},

      init : function(el /* jQuery object */, opts /* mixin */) {
          this.el = el;
          $.extend(this.config, opts);
      }
});
Communicate between components using a
centralized messaging hub (i.e. pub/sub).
myApp.common.Messaging = Class.extend({
    init : function() {
        this.el = $('<div class="message"/>').prependTo('body').hide();
        $.subscribe('/message/notification', $.proxy(this._showMessage, this));
    },

      _showMessage : function(msg) { /* ... */ },

      _hideMessage : function() { /* ... */ },

      _cleanup : function() { /* ... */ }
});




myApp.services._base = Class.extend({
    description : '',

      init : function(opts) {
          $.subscribe('/search/term', $.proxy(this._doSearch, this));
          $.publish('/message/notification',
             [ 'Service ' + this.description + ' added' ]
          );
      },

      _doSearch : function(term) { /* ... */ },
});
DRY and maintain separation of concerns.
$.proxy


Take control of your functions by specifying
the meaning of “this” inside of them.
myApp.services._base = Class.extend({
    description : '',

      init : function(opts) {
          $.subscribe('/search/term', $.proxy(this._doSearch, this));
          $.publish('/message/notification',
             [ 'Service ' + this.description + ' added' ]
          );
      },

      _doSearch : function(term) { /* ... */ },
});
$.fn.delegate


All the cool kids are using it
(say goodbye to $.fn.live)
myApp.widgets.Saved = Class.extend({

      init : function(el) {
          this.el = el;

           // event delegation for searching and removing searches
           this.el.delegate('li', 'click', $.proxy(this._doSearch, this));
           this.el.delegate('span.remove', 'click',
              $.proxy(this._removeSearch, this));
      },

      _doSearch : function(e) { /* ... */ },
      _removeSearch : function(e) { /* ... */ }
});
Tools for Building &
Dependency Management
              http://www.flickr.com/photos/flightsaber/2204113449/
Only a handful of solutions, none that I love.
RequireJS (building and loading)
LABjs (loading only)
modulr (building only)
Roll your own
Dojo?
Caveats
I’ve written plenty of code that didn’t work
this way. Sometimes for better, sometimes
for worse.
If your needs aren’t complex, don’t write
complex code to solve them. is approach
might be overkill for your project.
$(document).ready(function() {
    $('#myFeature li')
        .append('<div/>')
        .click(function() {
            var $this = $(this);
            var $div = $this.find('div');
            $div.load('foo.php?item=' +
                $this.attr('id'),
                function() {
                    $div.show();
                    $this.siblings()
                        .find('div').hide();
                }
            );
        })
});
is approach works really well for applications
with distinct but related pieces of functionality,
and for applications that are always evolving.
Other options for code org include plugins,
object literals, and prototypal inheritance.
anks.

rebeccamurphey.com
yayquery.com
twitter.com/rmurphey

http://pinboard.in/u:rmurphey/t:large-jquery-apps/
http://github.com/rmurphey/large-jquery-apps

Special thanks to Alex Sexton, Paul Irish, Adam Sontag, James Burke, and
Peter Higgins

Mais conteúdo relacionado

Mais procurados

Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UI
Rebecca Murphey
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
Md. Ziaul Haq
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
dmethvin
 

Mais procurados (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Matters of State
Matters of StateMatters of State
Matters of State
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Delivering a Responsive UI
Delivering a Responsive UIDelivering a Responsive UI
Delivering a Responsive UI
 
jQuery Namespace Pattern
jQuery Namespace PatternjQuery Namespace Pattern
jQuery Namespace Pattern
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
 
Javascript in Plone
Javascript in PloneJavascript in Plone
Javascript in Plone
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
 
Jquery plugin development
Jquery plugin developmentJquery plugin development
Jquery plugin development
 

Destaque

MySQL Query Optimization (Basics)
MySQL Query Optimization (Basics)MySQL Query Optimization (Basics)
MySQL Query Optimization (Basics)
Karthik .P.R
 
User Interface Design in Software Engineering SE15
User Interface Design in Software Engineering SE15User Interface Design in Software Engineering SE15
User Interface Design in Software Engineering SE15
koolkampus
 
Software engineering lecture notes
Software engineering lecture notesSoftware engineering lecture notes
Software engineering lecture notes
Siva Ayyakutti
 
Management ppt
Management pptManagement ppt
Management ppt
Yen Garcia
 

Destaque (20)

Vision Pacific Group Ltd
Vision Pacific Group LtdVision Pacific Group Ltd
Vision Pacific Group Ltd
 
Designing For Ajax
Designing For AjaxDesigning For Ajax
Designing For Ajax
 
PHP mysql Introduction database
 PHP mysql  Introduction database PHP mysql  Introduction database
PHP mysql Introduction database
 
Beginning Jquery In Drupal Theming
Beginning Jquery In Drupal ThemingBeginning Jquery In Drupal Theming
Beginning Jquery In Drupal Theming
 
Ajax for PHP Developers
Ajax for PHP DevelopersAjax for PHP Developers
Ajax for PHP Developers
 
BITS: Introduction to relational databases and MySQL - SQL
BITS: Introduction to relational databases and MySQL - SQLBITS: Introduction to relational databases and MySQL - SQL
BITS: Introduction to relational databases and MySQL - SQL
 
MySQL Query Optimization (Basics)
MySQL Query Optimization (Basics)MySQL Query Optimization (Basics)
MySQL Query Optimization (Basics)
 
MySQL Introduction
MySQL IntroductionMySQL Introduction
MySQL Introduction
 
Understanding angular js
Understanding angular jsUnderstanding angular js
Understanding angular js
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
Introduction to MySQL
Introduction to MySQLIntroduction to MySQL
Introduction to MySQL
 
MySQL Atchitecture and Concepts
MySQL Atchitecture and ConceptsMySQL Atchitecture and Concepts
MySQL Atchitecture and Concepts
 
User Interface Design in Software Engineering SE15
User Interface Design in Software Engineering SE15User Interface Design in Software Engineering SE15
User Interface Design in Software Engineering SE15
 
Mysql introduction
Mysql introduction Mysql introduction
Mysql introduction
 
Software engineering lecture notes
Software engineering lecture notesSoftware engineering lecture notes
Software engineering lecture notes
 
Priciples of management ppt final
Priciples of management ppt finalPriciples of management ppt final
Priciples of management ppt final
 
VISIONS OF THE FUTURE Little Rock 2016
VISIONS OF THE FUTURE Little Rock 2016VISIONS OF THE FUTURE Little Rock 2016
VISIONS OF THE FUTURE Little Rock 2016
 
Management ppt
Management pptManagement ppt
Management ppt
 
MySQL DBA OCP 1Z0-883
MySQL DBA OCP 1Z0-883MySQL DBA OCP 1Z0-883
MySQL DBA OCP 1Z0-883
 
Basic concept of management
Basic concept of managementBasic concept of management
Basic concept of management
 

Semelhante a Building Large jQuery Applications

international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
smueller_sandsmedia
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
OSCON Byrum
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
wpnepal
 

Semelhante a Building Large jQuery Applications (20)

Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScriptModular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Frontin like-a-backer
Frontin like-a-backerFrontin like-a-backer
Frontin like-a-backer
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
 
Building Robust jQuery Plugins
Building Robust jQuery PluginsBuilding Robust jQuery Plugins
Building Robust jQuery Plugins
 
jQuery
jQueryjQuery
jQuery
 
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
Ajax on drupal the right way - DrupalCamp Campinas, São Paulo, Brazil 2016
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
 
Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tips
 
JQuery In Drupal
JQuery In DrupalJQuery In Drupal
JQuery In Drupal
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 

Mais de Rebecca Murphey (8)

Getting Started with Mulberry
Getting Started with MulberryGetting Started with Mulberry
Getting Started with Mulberry
 
Introducing Mulberry
Introducing MulberryIntroducing Mulberry
Introducing Mulberry
 
DojoConf: Building Large Apps
DojoConf: Building Large AppsDojoConf: Building Large Apps
DojoConf: Building Large Apps
 
Lessons from-a-rewrite-gotham
Lessons from-a-rewrite-gothamLessons from-a-rewrite-gotham
Lessons from-a-rewrite-gotham
 
Lessons from a Rewrite
Lessons from a RewriteLessons from a Rewrite
Lessons from a Rewrite
 
Modern JavaScript
Modern JavaScriptModern JavaScript
Modern JavaScript
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryCleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQuery
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Último (20)

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 

Building Large jQuery Applications

  • 2. Me independent JavaScript developer based in Durham, N.C. contributor to O’Reilly’s jQuery Cookbook co-host of the yayQuery podcast code organization fanatic
  • 3. What counts as a large application? http://www.flickr.com/photos/hippie/2475855465/
  • 4. distinct but related pieces of functionality extensive server communication frequent updating of the page without reload
  • 5. jQuery out of the box doesn’t give us many tools for developing large applications; its essentially a DOM manipulation and Ajax library.
  • 6. at doesn’t stop people from building large applications with jQuery.
  • 7. $(document).ready(function() { $('#myFeature li') .append('<div/>') .click(function() { var $this = $(this); var $div = $this.find('div'); $div.load('foo.php?item=' + $this.attr('id'), function() { $div.show(); $this.siblings() .find('div').hide(); } ); }) });
  • 8. // NAVIGATION function togglePage(section) { // if the clicked section is already the current section AND we're in full page mode // minimize the current tab if (jQuery('#md_tab_'+ section).hasClass('current') && jQuery('#md_tab_'+ section + ' a').hasClass('md_fullpage')) { // alert('clicked section is current section AND fullpage mode is active; teaser should load'); // Minimize jQuery('#md_tabs_navigation a').removeClass('md_fullpage'); jQuery('.md_body').hide(); jQuery('#md_feature').slideDown('normal',function(){ var bodyContent = jQuery('#md_body_'+ section); bodyContent.fadeOut('normal',function(){ jQuery('#md_tabs_navigation a').each(function(){ var thisSection = jQuery(this).html().replace('<span<','').replace('</ span<',''); var thisSection_comp = thisSection.toLowerCase().replace(' ','_'); jQuery('#md_body_'+ thisSection_comp).load( '/app/modules/info/loadTeaser.php?sect='+ thisSection_comp, function(){ tb_init('.md_body a.thickbox, .md_body area.thickbox, .md_body input.thickbox'); bodyContent.animate({ height: 'toggle', opacity: 'toggle' },"slow"); } ); }); }); }); jQuery('#expandtabs span').empty().append('Expand Tabs'); } else { // if the clicked section is NOT the current section OR we're NOT in full page mode // then let's go to full page mode and show the whole tab
  • 9. How do you write an application that uses jQuery without making a tangled mess?
  • 10. e key is to think of our applications as small pieces of functionality, and then write our code accordingly.
  • 11. Patterns & Practices http://www.flickr.com/photos/docman/3270589892/
  • 12. Above all else: Use jQuery as the DOM and Ajax tool it is, not as a framework.
  • 13. Use classes to organize your code; write methods that do exactly one thing.
  • 14. myApp.common.Messaging = Class.extend({ animDuration : 500, hideDelay : 1500, init : function() { this.el = $('<div class="message"/>').prependTo('body').hide(); $.subscribe('/message/notification', $.proxy(this._showMessage, this)); }, _showMessage : function(msg) { var hide = $.proxy(this._hideMessage, this); this.el.append('<p>' + msg + '</p>'); if (!this.el.is(':visible')) { this.el.slideDown(this.animDuration, $.proxy(function() { this.showTimeout = setTimeout(hide, this.hideDelay); }, this)); } else { clearTimeout(this.showTimeout); this.showTimeout = setTimeout(hide, this.hideDelay); } }, _hideMessage : function() { this.el.slideUp(this.animDuration); this._cleanup(); }, _cleanup : function() { this.el.empty(); } });
  • 15. Use the server to send data, not markup; use a templating system (like mustache.js) to create markup on the client side.
  • 16. myApp.widgets.Tools = Class.extend({ itemTemplate : '<li>' + '<input type="checkbox" name="{{description}}" checked>' + '<label for="{{description}}">{{description}}</label>' + '</li>', services : [], init : function(el) { this.el = el; this.el.delegate('input', 'click', $.proxy(this._handleChoice, this)); $.subscribe('/service/add', $.proxy(this._handleAdd, this)); }, _handleChoice : function(e) { var input = $(e.target), service = input.attr('name'); $.publish('/service/' + service + '/toggle', [ input.is(':checked') ]); }, _handleAdd : function(service) { if ($.inArray(service, this.services) >= 0) { return; } var html = Mustache.to_html(this.itemTemplate, { description : service }); this.el.append(html); } });
  • 17. Use a consistent pattern for de ning components that have a DOM representation.
  • 18. var DomThinger = Class.extend({ config : {}, init : function(el /* jQuery object */, opts /* mixin */) { this.el = el; $.extend(this.config, opts); } });
  • 19. Communicate between components using a centralized messaging hub (i.e. pub/sub).
  • 20. myApp.common.Messaging = Class.extend({ init : function() { this.el = $('<div class="message"/>').prependTo('body').hide(); $.subscribe('/message/notification', $.proxy(this._showMessage, this)); }, _showMessage : function(msg) { /* ... */ }, _hideMessage : function() { /* ... */ }, _cleanup : function() { /* ... */ } }); myApp.services._base = Class.extend({ description : '', init : function(opts) { $.subscribe('/search/term', $.proxy(this._doSearch, this)); $.publish('/message/notification', [ 'Service ' + this.description + ' added' ] ); }, _doSearch : function(term) { /* ... */ }, });
  • 21. DRY and maintain separation of concerns.
  • 22. $.proxy Take control of your functions by specifying the meaning of “this” inside of them.
  • 23. myApp.services._base = Class.extend({ description : '', init : function(opts) { $.subscribe('/search/term', $.proxy(this._doSearch, this)); $.publish('/message/notification', [ 'Service ' + this.description + ' added' ] ); }, _doSearch : function(term) { /* ... */ }, });
  • 24. $.fn.delegate All the cool kids are using it (say goodbye to $.fn.live)
  • 25. myApp.widgets.Saved = Class.extend({ init : function(el) { this.el = el; // event delegation for searching and removing searches this.el.delegate('li', 'click', $.proxy(this._doSearch, this)); this.el.delegate('span.remove', 'click', $.proxy(this._removeSearch, this)); }, _doSearch : function(e) { /* ... */ }, _removeSearch : function(e) { /* ... */ } });
  • 26. Tools for Building & Dependency Management http://www.flickr.com/photos/flightsaber/2204113449/
  • 27. Only a handful of solutions, none that I love.
  • 28. RequireJS (building and loading) LABjs (loading only) modulr (building only) Roll your own Dojo?
  • 30. I’ve written plenty of code that didn’t work this way. Sometimes for better, sometimes for worse.
  • 31. If your needs aren’t complex, don’t write complex code to solve them. is approach might be overkill for your project.
  • 32. $(document).ready(function() { $('#myFeature li') .append('<div/>') .click(function() { var $this = $(this); var $div = $this.find('div'); $div.load('foo.php?item=' + $this.attr('id'), function() { $div.show(); $this.siblings() .find('div').hide(); } ); }) });
  • 33. is approach works really well for applications with distinct but related pieces of functionality, and for applications that are always evolving.
  • 34. Other options for code org include plugins, object literals, and prototypal inheritance.