javascript mouseover

J

John J

Hi there

I have the following code on a site that works as it should but I'd like to
understand how it works (a luxury I realise :).

I use it to change the colour of buttons on a menu when a mouse goes on and
off them as well as pre loading the 2nd images used to show the new button
colours.

It all looks incredibly complicated and try as I might to work it out I
haven't a clue what it is actually doing in each of the four sections. Any
help appreciated.

Cheers

John





<!--
function MM_swapImgRestore() { //v3.0
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a)&&x.oSrc;i++)
x.src=x.oSrc;
}

function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length;
i++)
if (a.indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a;}}
}

function MM_findObj(n, d) { //v4.01
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length)
{
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++)
x=d.forms[n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++)
x=MM_findObj(n,d.layers.document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array;
for(i=0;i<(a.length-2);i+=3)
if ((x=MM_findObj(a))!=null){document.MM_sr[j++]=x; if(!x.oSrc)
x.oSrc=x.src; x.src=a[i+2];}
}
//-->
 
Y

Yann-Erwan Perio

John said:
I have the following code on a site that works as it should but I'd like to
understand how it works (a luxury I realise :).

That's Dreamweaver's code; it is compressed to save a few bytes for the
user downloading the page, which makes it look complicated.

Actually, the functions are not as poor as is usually said here;
however, they have indeed some flaws, and more importantly they force a
certain use on the author, which prevent him from writing more than
averagely-good javascript.

This sort of comment was used previously for browsers not supporting
SCRIPT tags, therefore which used to present the javascript code as
text; such browsers are not in use anymore, the comment isn't therefore
needed anymore.

function MM_swapImgRestore() { //v3.0
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a)&&x.oSrc;i++)
x.src=x.oSrc;
}


This function is used to restore previous image sources, changed with
the MM_swapImage function. The MM_sr array contains references to the
images whose source has been swapped. It is iterated, and each image in
the array has its source (previously saved as an expando property on the
image object) set back.

The MM_sr array is created by the swapImage function, which permits to
swap several images' sources at the same time.

Too bad the for() loop tests for the MM_sr object at each iteration...

function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length;
i++)
if (a.indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a;}}
}


Function used to preload images; the MM_p array will hold all images to
be loaded. The function iterates the arguments passed to the function,
and if the current argument doesn't start with a "#" (better to use
charAt here), it creates a new image and assigns the source to the
argument's value, which in effect leads the browsers to issue a HTTP
request for the image (thus, preloading the image in the cache).

The function can be called many times, the array is only created once,
for the next calls it is simply used back.

Here, the function tests for d.images while it should test (if ever) for
the Image constructor. Moreover, it gets the arguments of the function
using the arguments property for the function, which is a deprecated way
since long. Eventually, the "#" test serves no purpose AFAICS.

function MM_findObj(n, d) { //v4.01
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length)
{
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++)
x=d.forms[n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++)
x=MM_findObj(n,d.layers.document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}


This function returns a reference to an element; the "n" argument is the
name/id of the element to be retrieved; "d" is the document to be
searched (when using frames, or in NN4 object model, you can have many
documents).

There is a first branch, allowing for a frame name to be specified,
using a "?"-based pattern - it would have been simpler to use a third
argument for the frame name, though - testing for the frame existence
would have been nice.

Then, the function starts looking up for the element having the name/id:
- first looking as a property of the document object (all HTML
collections root elements usually are added on the document object as
properties),
- then looking in the document.all collection,
- then looking in every present form,
- then looking in all layers, for NN4-based object models (repeating
uselessly the document.layers test at each iteration) - note the
recursive call to the findObj function, to find an element in a
contained document (a layer has a specific document),
- eventually using the document.getElementById standard method.

One of the big problems with this function is how it mixes names and
ids; name can be different from id; elements with the same name can have
multiple ids. Therefore, this function is to be used in a specific
context, not in all context (for instance, don't use it in a form
context, just use the regular form accessors there).

Eventually, other collections could have been searched, like
document.images, document.anchors etc.
function MM_swapImage() { //v3.0
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array;
for(i=0;i<(a.length-2);i+=3)
if ((x=MM_findObj(a))!=null){document.MM_sr[j++]=x; if(!x.oSrc)
x.oSrc=x.src; x.src=a[i+2];}
}


This function swaps the source for images, and stores old source in the
MM_sr array. You can swap many images at once, and restore all sources
using the restore function defined above.

Arguments passed to the function go always by three (therefore it would
have been better to pass object literals with three properties):
- the image name or ID, which is retrieved with the findObj object
(document.images should of course have been used),
- whatever you want (probably here for backward compatibility, I don't
know),
- the new source to be set.

Before setting the new source, the old source is saved as an expando of
the image object.


One big problem with generic functions like that is that they have to
address all possible issues, adding useless code for the situation, and
leaving the fallback to outside managers; before using them, it's better
to analyze thoroughly the problem and check whether a simple solution
cannot be used, with a neater conception, fitting the problem.
 
J

John J

Thanks very much for that! You clearly know your stuff.

Cheers

John




Yann-Erwan Perio said:
John said:
I have the following code on a site that works as it should but I'd like to
understand how it works (a luxury I realise :).

That's Dreamweaver's code; it is compressed to save a few bytes for the
user downloading the page, which makes it look complicated.

Actually, the functions are not as poor as is usually said here;
however, they have indeed some flaws, and more importantly they force a
certain use on the author, which prevent him from writing more than
averagely-good javascript.

This sort of comment was used previously for browsers not supporting
SCRIPT tags, therefore which used to present the javascript code as
text; such browsers are not in use anymore, the comment isn't therefore
needed anymore.

function MM_swapImgRestore() { //v3.0
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a)&&x.oSrc;i++)
x.src=x.oSrc;
}


This function is used to restore previous image sources, changed with
the MM_swapImage function. The MM_sr array contains references to the
images whose source has been swapped. It is iterated, and each image in
the array has its source (previously saved as an expando property on the
image object) set back.

The MM_sr array is created by the swapImage function, which permits to
swap several images' sources at the same time.

Too bad the for() loop tests for the MM_sr object at each iteration...

function MM_preloadImages() { //v3.0
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length;
i++)
if (a.indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a;}}
}


Function used to preload images; the MM_p array will hold all images to
be loaded. The function iterates the arguments passed to the function,
and if the current argument doesn't start with a "#" (better to use
charAt here), it creates a new image and assigns the source to the
argument's value, which in effect leads the browsers to issue a HTTP
request for the image (thus, preloading the image in the cache).

The function can be called many times, the array is only created once,
for the next calls it is simply used back.

Here, the function tests for d.images while it should test (if ever) for
the Image constructor. Moreover, it gets the arguments of the function
using the arguments property for the function, which is a deprecated way
since long. Eventually, the "#" test serves no purpose AFAICS.

function MM_findObj(n, d) { //v4.01
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length)
{
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++)
x=d.forms[n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++)
x=MM_findObj(n,d.layers.document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}


This function returns a reference to an element; the "n" argument is the
name/id of the element to be retrieved; "d" is the document to be
searched (when using frames, or in NN4 object model, you can have many
documents).

There is a first branch, allowing for a frame name to be specified,
using a "?"-based pattern - it would have been simpler to use a third
argument for the frame name, though - testing for the frame existence
would have been nice.

Then, the function starts looking up for the element having the name/id:
- first looking as a property of the document object (all HTML
collections root elements usually are added on the document object as
properties),
- then looking in the document.all collection,
- then looking in every present form,
- then looking in all layers, for NN4-based object models (repeating
uselessly the document.layers test at each iteration) - note the
recursive call to the findObj function, to find an element in a
contained document (a layer has a specific document),
- eventually using the document.getElementById standard method.

One of the big problems with this function is how it mixes names and
ids; name can be different from id; elements with the same name can have
multiple ids. Therefore, this function is to be used in a specific
context, not in all context (for instance, don't use it in a form
context, just use the regular form accessors there).

Eventually, other collections could have been searched, like
document.images, document.anchors etc.
function MM_swapImage() { //v3.0
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array;
for(i=0;i<(a.length-2);i+=3)
if ((x=MM_findObj(a))!=null){document.MM_sr[j++]=x; if(!x.oSrc)
x.oSrc=x.src; x.src=a[i+2];}
}


This function swaps the source for images, and stores old source in the
MM_sr array. You can swap many images at once, and restore all sources
using the restore function defined above.

Arguments passed to the function go always by three (therefore it would
have been better to pass object literals with three properties):
- the image name or ID, which is retrieved with the findObj object
(document.images should of course have been used),
- whatever you want (probably here for backward compatibility, I don't
know),
- the new source to be set.

Before setting the new source, the old source is saved as an expando of
the image object.


One big problem with generic functions like that is that they have to
address all possible issues, adding useless code for the situation, and
leaving the fallback to outside managers; before using them, it's better
to analyze thoroughly the problem and check whether a simple solution
cannot be used, with a neater conception, fitting the problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top