[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