Activate your free membership today | Log-in

Friday, February 8th, 2008

Refactoring your JavaScript for fun and profit

Category: JavaScript

<p>Our newest Ajaxian Chris Heilmann - London Yahoo! - has written a piece on his blog covering five things to do to a script before handing it over to the next developer.

He walks through a refactoring experience:

Let’s say the job was to add small link to every DIV in a document with the class collapsible that would show and hide the DIV. The first thing to do would be to use a library to get around the issues of cross-browser event handling. Let’s not concentrate on that for the moment but go for old school onevent handlers as we’re talking about different things here.

The code starts off as:

JAVASCRIPT:
  1.  
  2. collapser = function(){
  3.   var secs = document.getElementsByTagName('div');
  4.   for(var i=0;i<secs .length;i++){
  5.     if(secs[i].className.indexOf('collapsible')!==-1){
  6.       var p = document.createElement('p');
  7.       var a = document.createElement('a');
  8.       a.setAttribute('href','#');
  9.       a.onclick = function(){
  10.         var sec = this.parentNode.nextSibling;
  11.         if(sec.style.display === none'){
  12.           sec.style.display = 'block';
  13.           this.firstChild.nodeValue = 'collapse'
  14.         } else {
  15.           sec.style.display = 'none';
  16.           this.firstChild.nodeValue = 'expand'
  17.         }
  18.         return false;
  19.       };
  20.       a.appendChild(document.createTextNode('expand'));
  21.       p.appendChild(a);
  22.       secs[i].style.display = 'none';
  23.       secs[i].parentNode.insertBefore(p,secs[i]);
  24.     }
  25.   }
  26. }();

and then he walks through some steps:

  • Step 1: Remove look and feel
  • Step 2: Remove obvious speed issues
  • Step 3: Removing every label and name from the functional code
  • Step 4: Use human-readable variable and method names
  • Step 5: Comment, sign and possibly eliminate the last remaining clash with other scripts
  • Which has you ending up with:

    JAVASCRIPT:
    1.  
    2. //  Collapse and expand section of the page with a certain class
    3. //  written by Christian Heilmann, 07/01/08
    4. (function(){
    5.  
    6.   // Configuration, change CSS class names and labels here
    7.   var config = {
    8.     indicatorClass : 'collapsible',
    9.     collapsedClass : 'collapsed',
    10.     collapseLabel : 'collapse',
    11.     expandLabel : 'expand'
    12.   }
    13.  
    14.   var sections = document.getElementsByTagName('div');
    15.   for(var i=0,j=sections.length;i<j ;i++){
    16.     if(sections[i].className.indexOf(config.indicatorClass)!==-1){
    17.       sections[i].className += ' ' + config.collapsedClass;
    18.       var paragraph = document.createElement('p');
    19.       var triggerLink = document.createElement('a');
    20.       triggerLink.setAttribute('href','#');
    21.       triggerLink.onclick = toggleSection;
    22.       triggerLink.appendChild(document.createTextNode(config.expandLabel));
    23.       paragraph.appendChild(triggerLink);
    24.       sections[i].parentNode.insertBefore(paragraph,sections[i]);
    25.     }
    26.   }
    27.   function toggleSection(){
    28.     var section = this.parentNode.nextSibling;
    29.     if(section.className.indexOf(config.collapsedClass)!==-1){
    30.       section.className = section.className.replace(' ' + config.collapsedClass,'');
    31.       this.firstChild.nodeValue = config.collapseLabel
    32.     } else {
    33.       section.className += ' ' + config.collapsedClass;
    34.       this.firstChild.nodeValue = config.expandLabel
    35.     }
    36.     return false;
    37.   }
    38.  

    Related Content:

    • FAQ: Lotus Notes, Domino and JavaScript
      Caught in a JavaScript jam? Before posing a question to our SearchDomino.com experts, check out our list of frequently asked questions on JavaScript...
    • Refactoring: A Must for Supporting Web Projects
      The modern Web is growing more complex and sophisticated every day. Dynamic pages, context-sensitive content, personalized services, and asynchronous...
    • JavaScript Learning Guide
      This SearchDomino.com guide introduces you to JavaScript in a Notes/Domino environment, explains best practices and pitfalls to avoid and provides...
    • Ajax in Action excerpt: The Page as an Application
      Ajax applications can contain much more client-side code than a standard web application, and hence benefit much more from the order that patterns and...
    • Refactor that!
      Refactoring sounds a bit highfalutin. Refactoring is about reformatting existing code so that it is understandable and maintainable as it is...

    Posted by Dion Almaer at 8:12 am
    6 Comments

    ++++-
    4.2 rating from 12 votes

6 Comments »

Comments feed TrackBack URI

Step 0: check your strings are delimited correctly…

if(sec.style.display === none’){

:-P

Comment by Andy Stevens — February 8, 2008

I really don’t understand why should something that must be clicked be a anchor with “#” href. For that we have events that handles action.
Why not just plain span with onclick event ?

Comment by MaLi — February 8, 2008

You can’t do the same styling on a span as you can on a link on older browsers.

Comment by genericallyloud — February 8, 2008

@MaLi: I do it the same way, because links are usually already styled to look clickable ;)

Comment by besh — February 8, 2008

Actually it is because links and buttons are accessible by keyboard and for screen readers, spans with click events are not. If there is a thing in HTML that does the job, use this, as it has the job for a reason.

Comment by Chris Heilmann — February 8, 2008

And the element here should be a ‘button’ – if only styling those wasn’t such pain in the ass… But I agree that ‘a’ is much better then ‘span’ for example.

Comment by ffreak — February 9, 2008

Leave a comment

You must be logged in to post a comment.