johnny99
asked on
Decoding Macromedia's JS
Can someone please decode and annotate the Macromedia Image-Swapping code below please? It's dense, and -- I suspect deliberately -- obscure.
The best *explained* solution gets the points, not the quickest.
----- stuff in the HEAD -----
function MM_preloadImages() { //v2.0
if (document.images) {
var imgFiles = MM_preloadImages.arguments ;
if (document.preloadArray==nu ll) document.preloadArray = new Array();
var i = document.preloadArray.leng th;
with (document) for (var j=0; j<imgFiles.length; j++) if (imgFiles[j].charAt(0)!="# "){
preloadArray[i] = new Image;
preloadArray[i++].src = imgFiles[j];
} }
}
function MM_swapImgRestore() { //v2.0
if (document.MM_swapImgData != null)
for (var i=0; i<(document.MM_swapImgData .length-1) ; i+=2)
document.MM_swapImgData[i] .src = document.MM_swapImgData[i+ 1];
}
function MM_swapImage() { //v2.0
var i,j=0,objStr,obj,swapArray =new Array,oldArray=document.MM _swapImgDa ta;
for (i=0; i < (MM_swapImage.arguments.le ngth-2); i+=3) {
objStr = MM_swapImage.arguments[(na vigator.ap pName == 'Netscape')?i:i+1];
if ((objStr.indexOf('document .layers[') ==0 && document.layers==null) ||
(objStr.indexOf('document. all[') ==0 && document.all ==null))
objStr = 'document'+objStr.substrin g(objStr.l astIndexOf ('.'),objS tr.length) ;
obj = eval(objStr);
if (obj != null) {
swapArray[j++] = obj;
swapArray[j++] = (oldArray==null || oldArray[j-1]!=obj)?obj.sr c:oldArray [j];
obj.src = MM_swapImage.arguments[i+2 ];
} }
document.MM_swapImgData = swapArray; //used for restore
}
----- stuff in the BODY -----
onLoad="MM_preloadImages(' /img/foo.g if','/img/ foo2.gif', '#94274011 1960');
MM_preloadImages('/img/bar .gif','/im g/bar2','# 9427401281 10');
and so on and so on...
My immediate thoughts are:
* What the hell are those "#942740128110" numbers?
* How much of this code could be cleaned up?
Happy Whatever,
The best *explained* solution gets the points, not the quickest.
----- stuff in the HEAD -----
function MM_preloadImages() { //v2.0
if (document.images) {
var imgFiles = MM_preloadImages.arguments
if (document.preloadArray==nu
var i = document.preloadArray.leng
with (document) for (var j=0; j<imgFiles.length; j++) if (imgFiles[j].charAt(0)!="#
preloadArray[i] = new Image;
preloadArray[i++].src = imgFiles[j];
} }
}
function MM_swapImgRestore() { //v2.0
if (document.MM_swapImgData != null)
for (var i=0; i<(document.MM_swapImgData
document.MM_swapImgData[i]
}
function MM_swapImage() { //v2.0
var i,j=0,objStr,obj,swapArray
for (i=0; i < (MM_swapImage.arguments.le
objStr = MM_swapImage.arguments[(na
if ((objStr.indexOf('document
(objStr.indexOf('document.
objStr = 'document'+objStr.substrin
obj = eval(objStr);
if (obj != null) {
swapArray[j++] = obj;
swapArray[j++] = (oldArray==null || oldArray[j-1]!=obj)?obj.sr
obj.src = MM_swapImage.arguments[i+2
} }
document.MM_swapImgData = swapArray; //used for restore
}
----- stuff in the BODY -----
onLoad="MM_preloadImages('
MM_preloadImages('/img/bar
and so on and so on...
My immediate thoughts are:
* What the hell are those "#942740128110" numbers?
* How much of this code could be cleaned up?
Happy Whatever,
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
1. The number is for DM to identify the image used from the collection in the editor environment. - it is only used by DM to load the images - can be removed but then DM might be unhappy when you want to modify the images.
2. The onload will "postload" (because it is called onLoad and not directly in the head) the images used and is using an array to pass each image to this:
function MM_preloadImages() { //v2.0
if (document.images) { // does the browser support the images array? (NS3+ IE4+)
var imgFiles = MM_preloadImages.arguments ; // the parameters in the call - here: '/img/foo.gif','/img/foo2. gif','#942 740111960'
it is called twice - once per image
if (document.preloadArray==nu ll) // Did we already create the array to hold the images? e.g. have we been called before - if not
document.preloadArray = new Array(); // create it
var i = document.preloadArray.leng th; // how long is it now?
with (document) // shorthand
for (var j=0; j<imgFiles.length; j++) // loop through the parameters (three here)
if (imgFiles[j].charAt(0)!="# "){ // If it is an image and not the serial number
preloadArray[i] = new Image; // create a new image object
preloadArray[i++].src = imgFiles[j]; // load the image and store the name
To be continued...
2. The onload will "postload" (because it is called onLoad and not directly in the head) the images used and is using an array to pass each image to this:
function MM_preloadImages() { //v2.0
if (document.images) { // does the browser support the images array? (NS3+ IE4+)
var imgFiles = MM_preloadImages.arguments
it is called twice - once per image
if (document.preloadArray==nu
document.preloadArray = new Array(); // create it
var i = document.preloadArray.leng
with (document) // shorthand
for (var j=0; j<imgFiles.length; j++) // loop through the parameters (three here)
if (imgFiles[j].charAt(0)!="#
preloadArray[i] = new Image; // create a new image object
preloadArray[i++].src = imgFiles[j]; // load the image and store the name
To be continued...
3. the swap consists of two parts, the over and the out
Over:
function MM_swapImage() { //v2.0
// Initialise variables
var i,j=0,objStr,obj,
swapArray=new Array,
oldArray=document.MM_swapI mgData;
for (i=0; i < (MM_swapImage.arguments.le ngth-2); i+=3) { // loop through the parameters sent in hops of 3 and end on the last but 3 parameter
and for each one do
objStr = MM_swapImage.arguments[(na vigator.ap pName == 'Netscape')?i:i+1]; // if netscape use the argument 0, 3, 6 and if not use 1, 4, 7 and so on - assuming
onMouseOver="MM_swapImage( 'document. foo','docu ment.foo', 'foo1.jpg' ,'#9451258 22593')"
it is the same here for IE and Netscape and they only swap argument 0 or 1 (but dreamweaver can swap more in one mouseover)
if ((objStr.indexOf('document .layers[') ==0 && document.layers==null)
is the script set up to use netscape but we have no layers (e.g NS3)
|| or
(objStr.indexOf('document. all[') ==0 && document.all ==null))
is it set up to use IE and we are not IE4+ (perhaps IE3, but that would be a mistake)
objStr = 'document'+
objStr.substring(objStr.la stIndexOf( '.'),objSt r.length); // take the stuff from the last fullstop and on in the parameter (this would be the image object)
obj = eval(objStr); // get a string
if (obj != null) { // it won't be
swapArray[j++] = obj; // store what image we need to change
swapArray[j++] = (oldArray==null || oldArray[j-1]!=obj)?obj.sr c:oldArray [j]; // store what we change it from
obj.src = MM_swapImage.arguments[i+2 ]; // change the image to the third argument
document.MM_swapImgData = swapArray; //used for restore - takes a copy
4. restore:
function MM_swapImgRestore() { //v2.0
if (document.MM_swapImgData != null) // do we have an array with store stuff?
for (var i=0; i<(document.MM_swapImgData .length-1) ; i+=2) // run through it and for each imagelocation,
document.MM_swapImgData[i] .src = document.MM_swapImgData[i+ 1];
// restore it's original image
}
Hope this make sense.
I will post you a replacement in a sec ;-)
Michel
Over:
function MM_swapImage() { //v2.0
// Initialise variables
var i,j=0,objStr,obj,
swapArray=new Array,
oldArray=document.MM_swapI
for (i=0; i < (MM_swapImage.arguments.le
and for each one do
objStr = MM_swapImage.arguments[(na
onMouseOver="MM_swapImage(
it is the same here for IE and Netscape and they only swap argument 0 or 1 (but dreamweaver can swap more in one mouseover)
if ((objStr.indexOf('document
is the script set up to use netscape but we have no layers (e.g NS3)
|| or
(objStr.indexOf('document.
is it set up to use IE and we are not IE4+ (perhaps IE3, but that would be a mistake)
objStr = 'document'+
objStr.substring(objStr.la
obj = eval(objStr); // get a string
if (obj != null) { // it won't be
swapArray[j++] = obj; // store what image we need to change
swapArray[j++] = (oldArray==null || oldArray[j-1]!=obj)?obj.sr
obj.src = MM_swapImage.arguments[i+2
document.MM_swapImgData = swapArray; //used for restore - takes a copy
4. restore:
function MM_swapImgRestore() { //v2.0
if (document.MM_swapImgData != null) // do we have an array with store stuff?
for (var i=0; i<(document.MM_swapImgData
document.MM_swapImgData[i]
// restore it's original image
}
Hope this make sense.
I will post you a replacement in a sec ;-)
Michel
Sorry, I should elaborate:
if not IE4+ or NS4+, create a string like document.foo out of whatever is sent:
objStr = 'document'+
objStr.substring(objStr.la stIndexOf( '.'),objSt r.length); //
in all cases THEN force a string using eval
obj = eval(objStr); // get a string
if not IE4+ or NS4+, create a string like document.foo out of whatever is sent:
objStr = 'document'+
objStr.substring(objStr.la
in all cases THEN force a string using eval
obj = eval(objStr); // get a string
A shorter script would be something like
<html>
<head>
<script>
/* preload and swap (c) 1999-2000 Michel Plungjan */
if (document.images) { /* preload all images - put in function to "postload" */
var imgName = new Array('foo','bar');
var onImage = new Array();
var offImage = new Array();
for (i=0;i<onImages.length;i++ ) {
onImage[imgName] = new Image();
onImage[imgName].src = 'img/'+imgName[i] +'2.gif';
offImage[imgName] = new Image();
onImage[imgName].src = 'img/'+imgName[i] +'.gif';
}
}
function swap(imgName,on) {
if (!document.images) return;
if (on) document.images[imgName].s rc = onImage[imgName].src;
else document.images[imgName].s rc = onImage[imgName].src;
}
</script>
</head>
<body>
<A HREF="....." onMouseOver="swap('foo',1) "
onMouseOut="swap('foo',0)" ><IMG NAME="foo" WIDTH=32 HEIGHT=32 ALT="foo"></A>
<A HREF="....." onMouseOver="swap('bar',1) "
onMouseOut="swap('bar',0)" ><IMG NAME="bar" WIDTH=32 HEIGHT=32 ALT="foo"></A>
</body>
</html>
<html>
<head>
<script>
/* preload and swap (c) 1999-2000 Michel Plungjan */
if (document.images) { /* preload all images - put in function to "postload" */
var imgName = new Array('foo','bar');
var onImage = new Array();
var offImage = new Array();
for (i=0;i<onImages.length;i++
onImage[imgName] = new Image();
onImage[imgName].src = 'img/'+imgName[i] +'2.gif';
offImage[imgName] = new Image();
onImage[imgName].src = 'img/'+imgName[i] +'.gif';
}
}
function swap(imgName,on) {
if (!document.images) return;
if (on) document.images[imgName].s
else document.images[imgName].s
}
</script>
</head>
<body>
<A HREF="....." onMouseOver="swap('foo',1)
onMouseOut="swap('foo',0)"
<A HREF="....." onMouseOver="swap('bar',1)
onMouseOut="swap('bar',0)"
</body>
</html>
PS: I have not tested the script above as it is - I tried to write the shortest scrit I could think of. let me know if there are typos or such in it.
it assumes filenames like x.gif and x2.gif
where the x2.gif is the "over" image.
it also assume the name reused in the actual naming in the html: NAME="x"
If that is the case, all you need to change is the line with
var imgName = new Array('foo','bar');
and perhaps the .gif to .jpg if you use jpgs.
Michel
it assumes filenames like x.gif and x2.gif
where the x2.gif is the "over" image.
it also assume the name reused in the actual naming in the html: NAME="x"
If that is the case, all you need to change is the line with
var imgName = new Array('foo','bar');
and perhaps the .gif to .jpg if you use jpgs.
Michel
ASKER
Excellent of course as usual Michel, thank you.
I haven't had a moment to check your script, but I'm sure it works, and I'm very interested to see that a lot of the code is there for Dreamweaver's convenience, not mine...
I haven't had a moment to check your script, but I'm sure it works, and I'm very interested to see that a lot of the code is there for Dreamweaver's convenience, not mine...
Glad to be of service...
I dislike the macromedia script intensely since each time I have to add functionality to someone's mouseovers/links, I either have to work around it or rewrite it - I now have a few re-written versions like the above, but it is still a big hassle.
I do however recognise the need for a generalised script that can be extended as needed if the user adds more images or more mouseovers.
Michel
I dislike the macromedia script intensely since each time I have to add functionality to someone's mouseovers/links, I either have to work around it or rewrite it - I now have a few re-written versions like the above, but it is still a big hassle.
I do however recognise the need for a generalised script that can be extended as needed if the user adds more images or more mouseovers.
Michel
ASKER
Yeah I guess one of the things about the script above is that it works for all kinds of mouseovers, self-changing, other-image-changing, and both.
What I don't like about it is the length and the massive redundancy. naming no names but I'm looking at a page which is over 30Kb in size, and 3 Kb is the body tag, but there are only a few mouseovers on it -- the body tag "postloads" the same images, in some cases, seventeen times over...
I've also seen preloading JavaScript which has to run for each image on the page, whether it's a mouseover or not...
Thanks again.
What I don't like about it is the length and the massive redundancy. naming no names but I'm looking at a page which is over 30Kb in size, and 3 Kb is the body tag, but there are only a few mouseovers on it -- the body tag "postloads" the same images, in some cases, seventeen times over...
I've also seen preloading JavaScript which has to run for each image on the page, whether it's a mouseover or not...
Thanks again.
ASKER