Link to home
Start Free TrialLog in
Avatar of johnny99
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==null) document.preloadArray = new Array();
    var i = document.preloadArray.length;
    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_swapImgData;
  for (i=0; i < (MM_swapImage.arguments.length-2); i+=3) {
    objStr = MM_swapImage.arguments[(navigator.appName == 'Netscape')?i:i+1];
    if ((objStr.indexOf('document.layers[')==0 && document.layers==null) ||
        (objStr.indexOf('document.all[')   ==0 && document.all   ==null))
      objStr = 'document'+objStr.substring(objStr.lastIndexOf('.'),objStr.length);
    obj = eval(objStr);
    if (obj != null) {
      swapArray[j++] = obj;
      swapArray[j++] = (oldArray==null || oldArray[j-1]!=obj)?obj.src: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.gif','/img/foo2.gif','#942740111960');
MM_preloadImages('/img/bar.gif','/img/bar2','#942740128110');

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,











Avatar of johnny99
johnny99

ASKER

Edited text of question.
ASKER CERTIFIED SOLUTION
Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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','#942740111960'

it is called twice - once per image
                             
if (document.preloadArray==null)  // 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.length; // 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...

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_swapImgData;


for (i=0; i < (MM_swapImage.arguments.length-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[(navigator.appName == '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','document.foo','foo1.jpg','#945125822593')"

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.lastIndexOf('.'),objStr.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.src: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
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.lastIndexOf('.'),objStr.length); //

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].src = onImage[imgName].src;
   else document.images[imgName].src = 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>
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
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...

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
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.