Image swap only works in IE

L

LAshooter

I have a portfolio page which loads a dozen thumbnails and one large image.
A friend helped me code a script (below) which will swap out the large image
(named "imgLarg") when a different thumbnail is clicked. Both the thumbnail
and the enlargement are identically named, one is in /thumbs/ and one is in
/enlargements/ - tricky, huh? ;-) What's the easiest way to make this work
in other browsers as well?

<script language="JavaScript">
function enlarge() {
oSrcElem = event.srcElement;
imgLarge.src = oSrcElem.src.replace(/thumbs/,'images');
}
</script>


Thanks,
Wm
 
T

Thomas 'PointedEars' Lahn

LAshooter said:
I have a portfolio page which loads a dozen thumbnails and one large
image. A friend helped me code a script (below) which will swap out
the large image (named "imgLarg") when a different thumbnail is
clicked. Both the thumbnail and the enlargement are identically named,
one is in /thumbs/ and one is in /enlargements/ - tricky, huh? ;-)
What's the easiest way to make this work in other browsers as well?

Not to use it at all, because it is junk. Compare

<URL:http://pointedears.de/scripts/test/hoverMe>


PointedEars
 
L

LAshooter

The script works very well in IE, just not in other browsers. Your reference
displays a black screen with nothing but an "About" graphic at the top. Is
something supposed to work there???

Wm
 
R

RobG

LAshooter said:
I have a portfolio page which loads a dozen thumbnails and one large image.
A friend helped me code a script (below) which will swap out the large image
(named "imgLarg") when a different thumbnail is clicked. Both the thumbnail
and the enlargement are identically named, one is in /thumbs/ and one is in
/enlargements/ - tricky, huh? ;-) What's the easiest way to make this work
in other browsers as well?

<script language="JavaScript">

The language attribute is deprecated, type is required:

function enlarge() {
oSrcElem = event.srcElement;

Your use of 'event' (i.e. the event object) here is one factor that makes
your script IE-centric. There are two basic event models: W3C and IE [1].
But there is no need to use the event object at all - you can pass a
reference directly from the element clicked on using 'this'.

On your thumbnail, use an onclick attribute like:

<img onclick="enlarge(this);" ... >


then:

function enlarge (oSrcElem){
// ...


Now oSrcElem is a reference to the element that fired the click event
without using the event object. Using 'this' is much more reliable and
consistent across various browsers.

imgLarge.src = oSrcElem.src.replace(/thumbs/,'images');

Here 'imgLarge' is either the name or id of the large image element, right?
And there you have your second IE-centric bit of code. IE makes all
element names and ID properties of the global object, a rather silly idea
that causes all sorts of problems.

In other browsers, you can get a reference to a named image using the
images collection (part of DOM 0), so in Firefox:

document.images.imgLarge


is a reference to the the image element with a name or ID of 'imgLarge'.
For some unknown reason, IE doesn't support that, you have to use the index
number. So if imgLarge is the 5th image in the document:

document.images[4]


would do the trick (and would work in Firefox too).

Anyhow, you are probably best to use getElementById with fall back to
document.all if you want to support IE 4. Try the following:

function enlarge (oSrcElem)
{

var imgLarge;

if (document.getElementById){
imgLarge = document.getElementById('imgLarge');
} else if (document.all){
imgLarge = document.all['imgLarge'];
}
if (imgLarge){
imgLarge.src = oSrcElem.src.replace(/thumbs/,'images');
}

}
</script>


While compiling the above, it occurred to me that it may be OK to use:

function enlarge (oSrcElem)
{
if (!imgLarge && document.getElementById){
var imgLarge = document.getElementById('imgLarge');
}
if (imgLarge){
imgLarge.src = oSrcElem.src.replace(/thumbs/,'images');
}
}


Untested. Of course anyone without scripting will see nothing happen.



1. Read about the different event models here:

<URL:http://www.quirksmode.org/js/introevents.html>
 
R

Richard Cornford

RobG wrote:
document.images.imgLarge


is a reference to the the image element with a name or ID
of 'imgLarge'. For some unknown reason, IE doesn't support
that, you have to use the index number.

Are you certain of that. I have never seen IE fail to resolve a named
image as a property of the - document.images - object?

While compiling the above, it occurred to me that it may be
OK to use:

function enlarge (oSrcElem)
{
if (!imgLarge && document.getElementById){
var imgLarge = document.getElementById('imgLarge');
}
if (imgLarge){
imgLarge.src = oSrcElem.src.replace(/thumbs/,'images');
}
}


Untested.

It won't behave as implied, just as coded. The - var imgLarge - is not
conditional, function local variables are created prior to the execution
of any function body code so when the unqualified Identifier -
imgLarge - is first subject to the NOT operator it will resolve as a
local variable that has not yet been assigned a value, so - undefined -,
type convert to false and evaluate the NOT as true, always. And as the
result of - !imgLarge - is always true there is no point in carrying out
that test at all.

Richard.
 
L

Lasse Reichstein Nielsen

LAshooter said:
I have a portfolio page which loads a dozen thumbnails and one large image.
A friend helped me code a script (below) which will swap out the large image
(named "imgLarg") when a different thumbnail is clicked. Both the thumbnail
and the enlargement are identically named, one is in /thumbs/ and one is in
/enlargements/ - tricky, huh? ;-)

Not particularly. Your code suggests that the directories are actually
"thumbs" and "images". Which is it? I'll assume "enlargements" for now.
What's the easiest way to make this work in other browsers as well?

Rewrite from scratch. The script assumes that it runs in IE, and does
things that only work in the browser.
<script language="JavaScript">

For completeness, this is better (more standard compliant and works
just as well) written as:
function enlarge() {

When you want to work on the element that was clicked, the easiest
way to do that is to receive the element as an argument. It is
easy to provide, since it is available in the onclick event handler:
<img src="../thumbs/..." onclick="enlarge(this);">
Then receive it as:
function enlarge(thumbImage) {
oSrcElem = event.srcElement;

That makes this IE'ism unnecessary.
imgLarge.src = oSrcElem.src.replace(/thumbs/,'images');

Here you need to get a reference to the image element with name
"imgLarge". That is best done through the images collection:

document.images['imgLarge']

The assignment looks fine, as long as you are sure "thumbs" cannot
occour elsewhere in the string, previous to the instance to replace.

So:
document.images['imgLarge'].src =
thumbImage.src.replace(/thumbs/,"enlargements");
}
</script>


Good luck
/L
 
R

RobG

Richard said:
RobG wrote:



Are you certain of that. I have never seen IE fail to resolve a named
image as a property of the - document.images - object?

I /was/, but testing shows me to be wrong. I seem to remember that IE
didn't let you do it, I'm trying to track down where I got that idea from.

It won't behave as implied, just as coded. The - var imgLarge - is not
conditional, function local variables are created prior to the execution
of any function body code so when the unqualified Identifier -
imgLarge - is first subject to the NOT operator it will resolve as a
local variable that has not yet been assigned a value, so - undefined -,
type convert to false and evaluate the NOT as true, always. And as the
result of - !imgLarge - is always true there is no point in carrying out
that test at all.

Thanks for the explanation. Changing the first line to:

if (! window.imgLarge && document.getElementById){


gets it to work. I don't think I'd ever use it in real life though.
 
M

Michael Winter

Richard Cornford wrote:
[snip]
Are you certain of that. I have never seen IE fail to resolve a
named image as a property of the - document.images - object?

I /was/, but testing shows me to be wrong. I seem to remember that IE
didn't let you do it, I'm trying to track down where I got that idea
from.

You're probably confusing the images collection with the links
collection. The latter can only be indexed by ordinal number in IE.
However, with IE 6, one can use the namedItem method to obtain
references to source anchors (<a href="..."), though the equivalent dot-
or bracket-notation will still fail.

[snip]

Mike
 
T

Thomas 'PointedEars' Lahn

LAshooter said:
The script works very well in IE, just not in other browsers. Your
reference displays a black screen with nothing but an "About" graphic
at the top. Is something supposed to work there???

Yes, there is a hover effect on that graphic, facilitated with a far better
"Image swap" code as you presented. If you would have cared to read (the
source code), you would have known.
[Top post]

Score adjusted.


PointedEars
 
L

LAshooter

I did look at the source code, and thought it was a helluva lotta code for
what looks like a simple mouseover. But thanks for all your help anyways.


Thomas 'PointedEars' Lahn said:
LAshooter said:
The script works very well in IE, just not in other browsers. Your
reference displays a black screen with nothing but an "About" graphic
at the top. Is something supposed to work there???

Yes, there is a hover effect on that graphic, facilitated with a far
better
"Image swap" code as you presented. If you would have cared to read (the
source code), you would have known.
[Top post]

Score adjusted.


PointedEars
 
W

webdood

Here is a definitive answer for doing your image swap for all browsers.
The trick is to attach your event handler in such a way that it passes
the Event Object to your function (which applies only if your using
Netscape/FireFox) and to design your function so that it uses either
window.event (for IE) or the passed in Event Object (NS/FF).

<script language=javascript>
function enlarge(e) {
// Normalize the event object into standard Object regardless of
Browser
var _event=(window.event)? event : e;
// Obtain handle to actual IMG Object that triggered the event
var theImg = (_event.srcElement) ? _event.srcElement :
_event.currentTarget;
// Swap out the source path from the "thumbs" to the "enlargements"
directory
theImg.src = theImg.src.replace(/thumbs/i,'enlargements');
}
</script>

<img src="http://www.abc.com/images/thumbs/blahblah.gif"
onclick="enlarge(event)">

Shannon Norrell
 
R

RobG

webdood said:
Here is a definitive answer for doing your image swap for all browsers.

No, it's not for the reasons listed in at least two previous posts.

The trick is to attach your event handler in such a way that it passes
the Event Object to your function (which applies only if your using
Netscape/FireFox) and to design your function so that it uses either
window.event (for IE) or the passed in Event Object (NS/FF).

There is no need to use the event object, 'this' provides a
cross-browser solution without any code forking and much less code.

<script language=javascript>

The language attribute is deprecated, type is required.

[...]
// Swap out the source path from the "thumbs" to the "enlargements"
directory
theImg.src = theImg.src.replace(/thumbs/i,'enlargements');

'theImg' refers to what? Where was it defined? This relys on IE's
trick of turning names and IDs into global properties.

This solution is not suitable for a great many browsers and absolutely
not 'definitive'.

[...]
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top