SlideShare une entreprise Scribd logo
1  sur  29
Télécharger pour lire hors ligne
Cleaner, Leaner, Meaner
            Refactoring your JavaScript
            Rebecca Murphey • @rmurphey • rebeccamurphey.com

Thursday, December 2, 2010
http://github.com/rmurphey/refactor-jquery




                                                            2
Thursday, December 2, 2010
“... changing a software system in such a way
              that it does not alter the external behavior
              of the code yet improves its internal
              structure.”
                                         Martin Fowler, “Refactoring”




                                                                        3
Thursday, December 2, 2010
Why Refactor?
               Hint: Not just because it’s fun.
Thursday, December 2, 2010
“When you sit down and solve a
                             problem, that solution is
                             merely a rst draft.”
                                   Stoyan Stefanov, “JavaScript Patterns”




                                                                            5
Thursday, December 2, 2010
Internal rewards
               Increase maintainability
               Increase extensibility & reusability


               User experience rewards
               Improve page performance
               Increase testability (reduce bugs)



                                                      6
Thursday, December 2, 2010
Put another way: Refactoring will make your
               users happier, make your code cheaper to work
               with, or both.

                                                               7
Thursday, December 2, 2010
JavaScript
                             Code Smells
                             8 tell-tale signs your code needs some TLC




Thursday, December 2, 2010
$('#showMessage').click(function() {
                        $('<div>' +
                          '<h1>' + $('#messageTitle').val() + '</h1>' +
                          '<p>' + $('#messageText').val() + '</p>' +
                          '</div>')
                          .appendTo('#messageContainer')
                      });

                      // MINTY FRESH: Use templates instead
                      <script type="text/x-jquery-tmpl" id="messageTemplate">
                        <div>
                          <h1>${title}</h1>
                          <p>${text}</p>
                        </div>
                      </script>

                      $('#messageTemplate').template('messageTemplate');

                      $.tmpl('messageTemplate', {
                        title : $('#messageTitle').val(),
                        text : $('#messageText').val()
                      })
                      .appendTo('#messageContainer');




             HTML in your JavaScript
                                                                                9
Thursday, December 2, 2010
http://api.jquery.com/category/plugins/templates/
               http://github.com/janl/mustache.js/
               http://documentcloud.github.com/underscore/


                                                                   10
Thursday, December 2, 2010
$('p.special').click(function() {
                         $(this).css({
                           'color' : 'red',
                           'font-weight' : 'bold'
                         });
                      })

                      // MINTY FRESH: Keep presentation information in CSS
                      p.extraSpecial {
                        color: red;
                        font-weight: bold;
                      }

                      $('p.special').click(function() {
                        $(this).addClass('extraSpecial');
                      });




             Changing style information in JavaScript
                                                                             11
Thursday, December 2, 2010
function isItemInArray(item, arr) {
                        var inArray = false,
                            len = arr.length;

                          for (var i = 0; i < len; i++) {
                            if (item == arr[i]) {
                              inArray = true;
                            }
                          }

                          return inArray;
                      }

                      // MINTY FRESH: Use jQuery!
                      function isItemInArray(item, arr) {
                        return $.inArray(item, arr) > -1;
                      }




             Duplication of existing jQuery methods
                                                            12
Thursday, December 2, 2010
http://api.jquery.com/category/utilities/
               http://api.jquery.com/category/miscellaneous/




                                                               13
Thursday, December 2, 2010
$('a.thinger').each(function() {
                         $(this).attr('href', $(this).attr('href') + '?ajax=true');
                      });
                      $('a.thinger').hide();
                      $('#myButton').click(function(){
                         $('a.thinger').show();
                      })

                      // MINTY FRESH: Use the chain and setter functions!
                      var thingers = $('a.thinger'), // store selection in a var
                          button = $('#myButton');   // just in case!

                      thingers.attr('href', function(idx, oldVal) {
                        // pass a setter function & avoid the need
                        // to iterate over matches
                        return oldVal + '?ajax=true';
                      }).hide();

                      button.click(function() {
                        thingers.show();
                      });




             Repetition that jQuery lets you avoid
                                                                                      14
Thursday, December 2, 2010
$(document).ready(function() {
                        $('#enableAwesome').click(function() {
                          $('ul.foo li').each(function() {
                            var li = $(this);

                               li.data('name', li.html())
                                 .find('a.remove').click(function(e) {
                                   $.ajax({
                                      url : $(this).attr('href'),
                                      dataType : 'json',
                                      type : 'post',
                                      success : function(resp) {
                                        if (resp.ok) { li.remove(); }
                                      },
                                      error : console.log
                                   })
                                   e.preventDefault();
                                 });
                          })
                        });
                      });




             Deeply nested anonymous functions
                                                                         15
Thursday, December 2, 2010
// MINTY FRESH: Isolate functionality into an object with methods
                      var awesome = {
                        enableListItem : function() {
                           var li = $(this);
                          li.data('name', li.html());
                        },

                           removeListItem : function() {
                             var a = $(this),
                                 li = a.closest('li');

                             awesome.removeOnServer({
                                url : a.attr('href'),
                                success : function(resp) {
                                  if (resp.ok) { li.remove(); }
                                }
                              });
                           },

                           removeOnServer : function (config) {
                             var defaults = {
                                   type : 'post',
                                   dataType : 'json',
                                   error : console.log
                                 },
                                 settings = $.extend({}, defaults, config);

                               if (!settings.url) { return; }
                               $.ajax(config);
                           }
                      };




                                                                                          16
Thursday, December 2, 2010
$(document).ready(function() {
                        $('#enableAwesome').click(function() {
                          $('ul.foo li')
                            .each(awesome.enableListItem)
                            .delegate('a.remove', 'click', awesome.removeListItem);
                        });
                      });




                                                                                      17
Thursday, December 2, 2010
// SMELLY: Overtesting for truthiness
                      if (errorMsg != null && errorMsg.length > 0) {
                        // ...
                      }

                      // MINTY FRESH: Be as terse as you can
                      if (errorMsg && errorMsg.length) {
                        // ...
                      }




             Overtesting for truthiness
                                                                       18
Thursday, December 2, 2010
// SMELLY
                      if (total == null || total == "0") {
                        // ...
                      }

                      // MINTY FRESH
                      if (!parseInt(total, 10)) {
                        // ...
                      }




                                                             19
Thursday, December 2, 2010
// SMELLY
                      if (price == null) {
                        // ...
                      } else if(discountPrice != null && price == discountPrice) {
                        // ...
                      }

                      // MINTY FRESH
                      if (!price) {
                        // ...

                      // we already know that price isn't null,
                      // so why test if discountPrice is? if it's
                      // equal to price, we know it's not null
                      } else if (price == discountPrice) {
                        // ...
                      }




                                                                                     20
Thursday, December 2, 2010
function isItABigNumber(num) {
                        if(num > 5000) {
                          $('#myContainer').html('<p>It was a big number</p>');
                          $('#myInput').val(num);
                          $('.thinger').hide();
                        } else {
                          $('#myContainer').html('<p>It was not a big number</p>');
                          $('#myInput').val('');
                          $('.thinger').show();
                        }
                      }

                      // MINTY FRESH: Only repeat what needs repeating
                      function isItABigNumber(num) {
                        var big = num > 5000;

                          $('#myContainer').html(big ?
                            '<p>It was a big number</p>' :
                            '<p>It was not a big number</p>');
                          $('#myInput').val(big ? num : '');
                          $('.thinger')[big ? 'hide' : 'show']();
                      }




             Repetitive logic blocks
                                                                                      21
Thursday, December 2, 2010
function crazyConcatenation(selector, word1, word2, word3, repeat) {
                        var arr = [],
                            words = [],
                            joinedWords;

                          if (selector == null) { return; }
                          if (word1 == null) { return; }

                          if (word2 != null) { words.push(word2); }
                          if (word3 != null) { words.push(word3); }
                          if (!repeat) { repeat = 5; }

                          joinedWords = words.join(', ');

                          while (repeat--) { arr.push(joinedWords); }

                          $(selector).html(arr.join('<br/>'))
                      }

                      crazyConcatenation('#foo', 'Hello', null, null, 5);




             Passing a lot of arguments to a function
                                                                                             22
Thursday, December 2, 2010
// MINTY FRESH: Using an object instead
                      function crazyConcatenation(config) {
                        // indicate clearly what's required
                        if (
                          !config.selector ||
                          !config.words ||
                          !config.words.length
                        ) { return; }

                          var defaults = { repeat : 5 },
                              settings = $.extend({}, defaults, config),
                              joinedWords = settings.words.join(', ');

                          while (settings.repeat--) {
                            arr.push(joinedWords);
                          }

                          $(settings.selector).html(arr.join('<br/>'))
                      }

                      crazyConcatenation({
                        selector : '#foo',
                        words : [ 'foo', 'bar', 'baz' ],
                        repeat : 20
                      });




                                                                           23
Thursday, December 2, 2010
Advanced Moves
               Common patterns for improving your code
Thursday, December 2, 2010
“Writing to be read means writing code ... with
               the idea that someone else will read it. is
               fact alone will make you edit and think of better
               ways to solve the problem you have at hand.”
                                       Stoyan Stefanov, “JavaScript Patterns”


                                                                                25
Thursday, December 2, 2010
example add the same behavior to similar
               content without depending on IDs




                                                          26
Thursday, December 2, 2010
example cache XHR responses, and create an
               API to a server-side service




                                                            27
Thursday, December 2, 2010
example refactor a portlet
                             to use the jQuery UI widget
                             factory




                                                           28
Thursday, December 2, 2010
rebeccamurphey.com

                             blog.rebeccamurphey.com

                             @rmurphey

                             http://github.com/rmurphey/refactor-jquery

                             http://pinboard.in/u:rmurphey/t:refactor/


                             Presented at the 2010 Rich Web Experience




                                                                          29
Thursday, December 2, 2010

Contenu connexe

Tendances

Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
Md. Ziaul Haq
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
Rebecca Murphey
 

Tendances (19)

Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
jQuery
jQueryjQuery
jQuery
 
Mulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development ToolkitMulberry: A Mobile App Development Toolkit
Mulberry: A Mobile App Development Toolkit
 
Dojo Confessions
Dojo ConfessionsDojo Confessions
Dojo Confessions
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented Architecture
 
Ext GWT 3.0 Theming and Appearances
Ext GWT 3.0 Theming and AppearancesExt GWT 3.0 Theming and Appearances
Ext GWT 3.0 Theming and Appearances
 
A New Baseline for Front-End Devs
A New Baseline for Front-End DevsA New Baseline for Front-End Devs
A New Baseline for Front-End Devs
 
Drupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of UsageDrupal Entities - Emerging Patterns of Usage
Drupal Entities - Emerging Patterns of Usage
 
Building Sencha Themes
Building Sencha ThemesBuilding Sencha Themes
Building Sencha Themes
 
Email Program By Marcelo
Email Program By MarceloEmail Program By Marcelo
Email Program By Marcelo
 
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
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3Transparent Object Persistence with FLOW3
Transparent Object Persistence with FLOW3
 
2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Drupal csu-open atriumname
Drupal csu-open atriumnameDrupal csu-open atriumname
Drupal csu-open atriumname
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.com
 

Similaire à Cleaner, Leaner, Meaner: Refactoring your jQuery

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
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Know
girish82
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
Jarod Ferguson
 

Similaire à Cleaner, Leaner, Meaner: Refactoring your jQuery (20)

The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
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
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Organizing Code with JavascriptMVC
Organizing Code with JavascriptMVCOrganizing Code with JavascriptMVC
Organizing Code with JavascriptMVC
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
jQuery Loves You
jQuery Loves YoujQuery Loves You
jQuery Loves You
 
jQuery - Tips And Tricks
jQuery - Tips And TricksjQuery - Tips And Tricks
jQuery - Tips And Tricks
 
jQuery's Secrets
jQuery's SecretsjQuery's Secrets
jQuery's Secrets
 
Jquery optimization-tips
Jquery optimization-tipsJquery optimization-tips
Jquery optimization-tips
 
jQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformancejQuery Anti-Patterns for Performance
jQuery Anti-Patterns for Performance
 
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 JavascriptjQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
jQuery UI Widgets, Drag and Drop, Drupal 7 Javascript
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Know
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
A Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NETA Rich Web experience with jQuery, Ajax and .NET
A Rich Web experience with jQuery, Ajax and .NET
 
jQuery
jQueryjQuery
jQuery
 
How te bring common UI patterns to ADF
How te bring common UI patterns to ADFHow te bring common UI patterns to ADF
How te bring common UI patterns to ADF
 
Jquery examples
Jquery examplesJquery examples
Jquery examples
 
Jquery plugin development
Jquery plugin developmentJquery plugin development
Jquery plugin development
 

Plus 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
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
 

Dernier

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Dernier (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
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
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

Cleaner, Leaner, Meaner: Refactoring your jQuery

  • 1. Cleaner, Leaner, Meaner Refactoring your JavaScript Rebecca Murphey • @rmurphey • rebeccamurphey.com Thursday, December 2, 2010
  • 2. http://github.com/rmurphey/refactor-jquery 2 Thursday, December 2, 2010
  • 3. “... changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.” Martin Fowler, “Refactoring” 3 Thursday, December 2, 2010
  • 4. Why Refactor? Hint: Not just because it’s fun. Thursday, December 2, 2010
  • 5. “When you sit down and solve a problem, that solution is merely a rst draft.” Stoyan Stefanov, “JavaScript Patterns” 5 Thursday, December 2, 2010
  • 6. Internal rewards Increase maintainability Increase extensibility & reusability User experience rewards Improve page performance Increase testability (reduce bugs) 6 Thursday, December 2, 2010
  • 7. Put another way: Refactoring will make your users happier, make your code cheaper to work with, or both. 7 Thursday, December 2, 2010
  • 8. JavaScript Code Smells 8 tell-tale signs your code needs some TLC Thursday, December 2, 2010
  • 9. $('#showMessage').click(function() { $('<div>' + '<h1>' + $('#messageTitle').val() + '</h1>' + '<p>' + $('#messageText').val() + '</p>' + '</div>') .appendTo('#messageContainer') }); // MINTY FRESH: Use templates instead <script type="text/x-jquery-tmpl" id="messageTemplate"> <div> <h1>${title}</h1> <p>${text}</p> </div> </script> $('#messageTemplate').template('messageTemplate'); $.tmpl('messageTemplate', { title : $('#messageTitle').val(), text : $('#messageText').val() }) .appendTo('#messageContainer'); HTML in your JavaScript 9 Thursday, December 2, 2010
  • 10. http://api.jquery.com/category/plugins/templates/ http://github.com/janl/mustache.js/ http://documentcloud.github.com/underscore/ 10 Thursday, December 2, 2010
  • 11. $('p.special').click(function() { $(this).css({ 'color' : 'red', 'font-weight' : 'bold' }); }) // MINTY FRESH: Keep presentation information in CSS p.extraSpecial { color: red; font-weight: bold; } $('p.special').click(function() { $(this).addClass('extraSpecial'); }); Changing style information in JavaScript 11 Thursday, December 2, 2010
  • 12. function isItemInArray(item, arr) { var inArray = false, len = arr.length; for (var i = 0; i < len; i++) { if (item == arr[i]) { inArray = true; } } return inArray; } // MINTY FRESH: Use jQuery! function isItemInArray(item, arr) { return $.inArray(item, arr) > -1; } Duplication of existing jQuery methods 12 Thursday, December 2, 2010
  • 13. http://api.jquery.com/category/utilities/ http://api.jquery.com/category/miscellaneous/ 13 Thursday, December 2, 2010
  • 14. $('a.thinger').each(function() { $(this).attr('href', $(this).attr('href') + '?ajax=true'); }); $('a.thinger').hide(); $('#myButton').click(function(){ $('a.thinger').show(); }) // MINTY FRESH: Use the chain and setter functions! var thingers = $('a.thinger'), // store selection in a var button = $('#myButton'); // just in case! thingers.attr('href', function(idx, oldVal) { // pass a setter function & avoid the need // to iterate over matches return oldVal + '?ajax=true'; }).hide(); button.click(function() { thingers.show(); }); Repetition that jQuery lets you avoid 14 Thursday, December 2, 2010
  • 15. $(document).ready(function() { $('#enableAwesome').click(function() { $('ul.foo li').each(function() { var li = $(this); li.data('name', li.html()) .find('a.remove').click(function(e) { $.ajax({ url : $(this).attr('href'), dataType : 'json', type : 'post', success : function(resp) { if (resp.ok) { li.remove(); } }, error : console.log }) e.preventDefault(); }); }) }); }); Deeply nested anonymous functions 15 Thursday, December 2, 2010
  • 16. // MINTY FRESH: Isolate functionality into an object with methods var awesome = { enableListItem : function() { var li = $(this); li.data('name', li.html()); }, removeListItem : function() { var a = $(this), li = a.closest('li'); awesome.removeOnServer({ url : a.attr('href'), success : function(resp) { if (resp.ok) { li.remove(); } } }); }, removeOnServer : function (config) { var defaults = { type : 'post', dataType : 'json', error : console.log }, settings = $.extend({}, defaults, config); if (!settings.url) { return; } $.ajax(config); } }; 16 Thursday, December 2, 2010
  • 17. $(document).ready(function() { $('#enableAwesome').click(function() { $('ul.foo li') .each(awesome.enableListItem) .delegate('a.remove', 'click', awesome.removeListItem); }); }); 17 Thursday, December 2, 2010
  • 18. // SMELLY: Overtesting for truthiness if (errorMsg != null && errorMsg.length > 0) { // ... } // MINTY FRESH: Be as terse as you can if (errorMsg && errorMsg.length) { // ... } Overtesting for truthiness 18 Thursday, December 2, 2010
  • 19. // SMELLY if (total == null || total == "0") { // ... } // MINTY FRESH if (!parseInt(total, 10)) { // ... } 19 Thursday, December 2, 2010
  • 20. // SMELLY if (price == null) { // ... } else if(discountPrice != null && price == discountPrice) { // ... } // MINTY FRESH if (!price) { // ... // we already know that price isn't null, // so why test if discountPrice is? if it's // equal to price, we know it's not null } else if (price == discountPrice) { // ... } 20 Thursday, December 2, 2010
  • 21. function isItABigNumber(num) { if(num > 5000) { $('#myContainer').html('<p>It was a big number</p>'); $('#myInput').val(num); $('.thinger').hide(); } else { $('#myContainer').html('<p>It was not a big number</p>'); $('#myInput').val(''); $('.thinger').show(); } } // MINTY FRESH: Only repeat what needs repeating function isItABigNumber(num) { var big = num > 5000; $('#myContainer').html(big ? '<p>It was a big number</p>' : '<p>It was not a big number</p>'); $('#myInput').val(big ? num : ''); $('.thinger')[big ? 'hide' : 'show'](); } Repetitive logic blocks 21 Thursday, December 2, 2010
  • 22. function crazyConcatenation(selector, word1, word2, word3, repeat) { var arr = [], words = [], joinedWords; if (selector == null) { return; } if (word1 == null) { return; } if (word2 != null) { words.push(word2); } if (word3 != null) { words.push(word3); } if (!repeat) { repeat = 5; } joinedWords = words.join(', '); while (repeat--) { arr.push(joinedWords); } $(selector).html(arr.join('<br/>')) } crazyConcatenation('#foo', 'Hello', null, null, 5); Passing a lot of arguments to a function 22 Thursday, December 2, 2010
  • 23. // MINTY FRESH: Using an object instead function crazyConcatenation(config) { // indicate clearly what's required if ( !config.selector || !config.words || !config.words.length ) { return; } var defaults = { repeat : 5 }, settings = $.extend({}, defaults, config), joinedWords = settings.words.join(', '); while (settings.repeat--) { arr.push(joinedWords); } $(settings.selector).html(arr.join('<br/>')) } crazyConcatenation({ selector : '#foo', words : [ 'foo', 'bar', 'baz' ], repeat : 20 }); 23 Thursday, December 2, 2010
  • 24. Advanced Moves Common patterns for improving your code Thursday, December 2, 2010
  • 25. “Writing to be read means writing code ... with the idea that someone else will read it. is fact alone will make you edit and think of better ways to solve the problem you have at hand.” Stoyan Stefanov, “JavaScript Patterns” 25 Thursday, December 2, 2010
  • 26. example add the same behavior to similar content without depending on IDs 26 Thursday, December 2, 2010
  • 27. example cache XHR responses, and create an API to a server-side service 27 Thursday, December 2, 2010
  • 28. example refactor a portlet to use the jQuery UI widget factory 28 Thursday, December 2, 2010
  • 29. rebeccamurphey.com blog.rebeccamurphey.com @rmurphey http://github.com/rmurphey/refactor-jquery http://pinboard.in/u:rmurphey/t:refactor/ Presented at the 2010 Rich Web Experience 29 Thursday, December 2, 2010