[thelist] Pontification on object and method detection (was: Wanted: thedefinitive fool-proof mouseover JavaScript)

Richard Bennett mail at richardinfo.com
Fri Jun 29 09:03:30 CDT 2001


Hi,
> Yup.  Remember, though, that the alternative script only came
> up because I thought *cough* that testing for document.images
> still resulted in JS Image errors for IE 3 (and so I suspected
> on other older browsers too).

Although this approach wasn't specifically necessary as you found out, it's
always a nice option to keep in mind.

> (And I'd like to see a ref to formal docs that say it's
> okay to define the same function in consecutive scripts.)

Of course you can write the same function more than once, (although this is
not often done in consecutive scripts, that makes no difference) it's the
whole foundation of javascript inheritance, and of overwriting
properties/functions, and prototyping.
want to try? put this on a page, and call an alert:

function alert(e){
    window.status="Your alert was: "+e
}
This overwrites the alert() function.

Aside from the testing for objects issue, there are one or two things I'd
like to comment on in your code.
Firstly the use of eval(). Although perfectly legitimate, I've found it a
function to avoid whenever possible.
It slows your scripts down, by evaluating the expression each time, and can
cause the strangest bugs, as its results are not always clear.
It's a bit like using setTimeout to slow bit's of code down, a horrible
hack, only used if all else fails.
another way to re-write your img_act() function without using eval would be:

  function img_inact(imgName){
       document.images[imgName].src=self[imgName+"off"].src
  }

This uses the "self" reference, which is the window object.

Another thing, the code as it stands now will fail miserably in NS4, if the
links on the page are nested in a <div> (as most menus of mouse-over links
are), as NS4 creates a new document object for each level of nesting, so if
you have this:

<div id="menu" style="position: absolute; top: 200; left: 200;">
        <a href="./" onMouseover="img_act('libr')"
onMouseout="img_inact('libr')" class="nul">
                <img src="b-libr0.gif" name="libr" border="0" alt=""
width="60" height="50"></a>
        <a href="./" onMouseover="img_act('abou')"
onMouseout="img_inact('abou')" class="nul">
                <img src="b-abou0.gif" name="abou" border="0" alt=""
width="60" height="50"></a>
        <a href="./" onMouseover="img_act('cont')"
onMouseout="img_inact('cont')" class="nul">
                <img src="b-cont0.gif" name="cont" border="0" alt=""
width="60" height="50"></a>
<div>

You'll need to use this reference in NS4:
    document.menu.document.images[imgName].src=...

So suddenly the whole idea is less robust than it seemed to start off with.
What we can do, is pass the image object to the img_inact() function,
instead of just it's name. As the image is inside the <a href> link, we can
access it simply by name, like this (note: no quotes around the image name):

<a href="./" onMouseover="img_act(libr)"  onMouseout="img_inact(libr)"
class="nul">
        <img src="b-libr0.gif" name="libr" border="0" alt="" width="60"
height="50"></a>

And the change our function to this:

  function img_inact(obj){
           obj.src=self[obj.name+"off"].src
  }

Now we can access the images, however deeply they're nested also in NS4.
This can then either test for document.images, or use your 1.1 test.

If you do not support javascript 1.0 browsers, you can condense it to this:

<a href="./" onMouseover="libr.src=libron.src"
onMouseout="libr.src=libroff.src" class="nul">
        <img src="b-libr0.gif" name="libr" border="0" alt="" width="60"
height="50"></a>

and this script:
<SCRIPT LANGUAGE="JavaScript1.1">
<!--
  libron = new Image(60,50);
  libron.src = "b-libr0x.gif";
  libroff = new Image(60,50);
  libroff.src = "b-libr0.gif";
// -->
</SCRIPT>

That looks kind of familiar, nice and simple, then of course you could loop
your preload code

Sorry for the long post, started rambling i guess.

I was also wondering what this bit was for: class="nul" I guess the one l
was a typo, but why specify a null?

Cheers,
Richard Bennett

mail at richardinfo.com
www.richardinfo.com

Richard Bennett
Independent Software Consultant










More information about the thelist mailing list