[Javascript] Code optimization

Paul Novitski paul at juniperwebcraft.com
Tue Aug 8 17:14:06 CDT 2006


At 01:32 PM 8/8/2006, Terry Riegel wrote:
>Paul,
>
>The page I am working on simplifying is part of a much more
>complicated page. I am not a very good Javascript programmer,
>actually I would consider myself a Javascript hacker. I am working on
>learning though.
>
>http://client1.riegels.com/pages/start/filemanager/entry.html
>
>If you go to the link above you can use your email address to see the
>page I am trying to simplify.
>
>The page I am focusing my efforts on is the left bar. It is a listing
>of the files in the server directory, and it can become a large file.
>I would like to make my html much smaller by removing inline Javascript.



Hi Terry,

Ah, now I remember, you're the one building the wonderful file 
manager in JavaScript.

Separating your js from html isn't difficult, but will require recoding.

Here's a bit of your core code:

<body topmargin=0 leftmargin=0 marginwidth=0 marginheight=0 
onLoad="top.frames['details'].document.location.replace('http://client1.riegels.com/pages/htmlos/007.2.125743402419991261'); 
document.browseformhere['fm_list'].value = ''; 
document.browseform['fm_list'].value = ''; 
top.frames['tpbr'].document.searchform['fm_searchtext'].value='SEARCH';">

<div id="browsefiles">

<div class="nor" id=".TEMP"><a href="javascript:void;" 
onclick="changedest2('.TEMP','lkd');"><img 
src="/clearimage/images/lkd-small.gif" border="0" width="12" 
height="12" align="left"></a><a 
href="javascript:changedest('.TEMP','lkd')" 
ondblclick="changedest2('.TEMP','lkd')">.TEMP</a></div>

<div class="nor" id="clearimage"><a 
href="javascript:changedest2('clearimage','DIR')"><img 
src="/clearimage/images/dir-small.gif" border="0" width="12" 
height="12" align="left"></a><a 
href="javascript:changedest('clearimage','DIR')" 
ondblclick="changedest2('clearimage','DIR')">clearimage</a></div>

<div class="nor" id="filemanager"><a 
href="javascript:changedest2('filemanager','DIR')"><img 
src="/clearimage/images/dir-small.gif" border="0" width="12" 
height="12" align="left"></a><a 
href="javascript:changedest('filemanager','DIR')" 
ondblclick="changedest2('filemanager','DIR')">filemanager</a></div>
...


1) You can replace the javascript in your BODY tag with a 
window.onload statement in your linked js file:

window.onload = jsInit;

function jsInit()
{
         top.frames['details'].document.location.replace('http://client1.riegels.com/pages/htmlos/007.2.125743402419991261');
         document.browseformhere['fm_list'].value = '';
         document.browseform['fm_list'].value = '';
         top.frames['tpbr'].document.searchform['fm_searchtext'].value='SEARCH';
}

Because you might have multiple javascript files, all vying for that 
one window.onload slot, you can concatenate onload functions.  Here's 
one method:

         // get current onload function
         var load1234 = window.onload;

         // do this on page load:
         window.onload = function()
         {
                         // if there was already an onload function, run it now
                         if (load1234) load1234();

                 // then run your onload function
                 jsInit();
         }




2) I'd like to suggest a simplification of your markup.  Here's the 
folder type:

         <div
         class="nor"
         id="filemanager"
         >
                 <a
                 href="javascript:changedest2('filemanager','DIR')"
                 >
                         <img
                         src="/clearimage/images/dir-small.gif"
                         border="0"
                         width="12"
                         height="12"
                         align="left"
                         >
                 </a>
                 <a
                 href="javascript:changedest('filemanager','DIR')"
                 ondblclick="changedest2('filemanager','DIR')"
                 >
                         filemanager
                 </a>
         </div>

The difference between the two anchors appears to be that the first 
one surrounding the image doesn't have a double-click applied.  You 
want to honor the double-click on the text but not on the 
image.  Using two anchors to accomplish this seems excessive, 
especially since you're applying all your click behaviors with javascript.

Your page doesn't do anything if javascript is disabled.  Therefore 
is there really any reason to have anchors in the markup?  I would 
include them in a 'progressive enhancement' page in which the anchors 
still accomplish the goal in the absence of javascript, if perhaps 
more slowly.  But in this case if you're really determined not to 
serve users without javascript then I suggest there's no reason to 
clutter your markup with anchors.  Mouse behaviors can be applied to 
any element.

You apply the intial class name "nor" to all elements both in your 
markup and in your javascript initialization routine, which does so 
by naming each DIV individually.  I would eliminate this redundancy, 
probably including them in the markup so their styles take effect 
more quickly on page load.  If you want to initialize them in 
jvavascript, you can do so using the same loop used to apply 
behaviors to the anchors, without needing to know their individual ids.

Personally I would also mark it up as an unordered list, something like:

<ul id="browsefiles">
         <li id="filemanager">
                 <img src="..." >
                 filemanager
         </li>
         ...

...then apply the onclick to the LI and the ondblclick to the 2nd 
child (the text node).

However, getting back to your original markup:


3) Applying the mouse behaviors to your elements:

                 // don't run this code if not DOM-aware
                 if (!document.getElementById) return;

         // point to the container
         var oParent = document.getElementById("browsefiles");

                 // bail if not found
                 if (!oParent) return;

         // get array of all list items
         var aItems = document.getElementsByTagName("DIV");

                 // bail if not found
                 if (!aItems) return;

         // for each item in the list of file nodes
         for (iItem = 0; iItem < aItems.length; iItem++)
         {
                 // get array of anchors in the list item
                 var aAnchors = aItems[iItem].getElementsByTagName("A");

                         // apply behaviors to the image link
                         if (aAnchors[0])
                         {
                                 aAnchors[0].onclick = jsOpenDir;
                         }

                         // apply behaviors to the text link
                         if (aAnchors[1])
                         {
                                 aAnchors[1].onclick = jsSelectItem;
                                 aAnchors[1].ondblclick = jsOpenDir;
                         }
         }


// do this when an item is single-clicked
function jsSelectItem(evt)
{
         // cancel event-bubbling
                 if (evt) { event = evt; }
         event.cancelBubble = true;

         var sId = this.parentNode.id;
                 if (sId) changedest(sId, 'DIR');
}



// do this when an item is double-clicked
function jsOpenDir(evt)
{
         // cancel event-bubbling
                 if (evt) { event = evt; }
         event.cancelBubble = true;

         var sId = this.parentNode.id;
                 if (sId) changedest2(sId, 'DIR');
}

etc.

Here's a live example of just this much code:
http://juniperwebcraft.com/test/triegel20060808.html

I've probably glossed over some of the details of your full-blown 
code, but I hope this will get you started.  Let me know if you'd 
like further guidance.

Regards,
Paul




More information about the Javascript mailing list