Image swap only works in IE

Discussion in 'Javascript' started by LAshooter, Mar 5, 2006.

  1. LAshooter

    LAshooter Guest

    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
     
    LAshooter, Mar 5, 2006
    #1
    1. Advertisements

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

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


    PointedEars
     
    Thomas 'PointedEars' Lahn, Mar 5, 2006
    #2
    1. Advertisements

  3. LAshooter

    LAshooter Guest

    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
     
    LAshooter, Mar 5, 2006
    #3
  4. LAshooter

    RobG Guest

    The language attribute is deprecated, type is required:

    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.

    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');
    }


    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>
     
    RobG, Mar 5, 2006
    #4
  5. 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?

    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.
     
    Richard Cornford, Mar 5, 2006
    #5
  6. Not particularly. Your code suggests that the directories are actually
    "thumbs" and "images". Which is it? I'll assume "enlargements" for now.
    Rewrite from scratch. The script assumes that it runs in IE, and does
    things that only work in the browser.
    For completeness, this is better (more standard compliant and works
    just as well) written as:
    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) {
    That makes this IE'ism unnecessary.
    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");

    Good luck
    /L
     
    Lasse Reichstein Nielsen, Mar 5, 2006
    #6
  7. LAshooter

    RobG Guest

    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.

    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.
     
    RobG, Mar 5, 2006
    #7
  8. 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
     
    Michael Winter, Mar 5, 2006
    #8
  9. 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.
    Score adjusted.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Mar 5, 2006
    #9
  10. LAshooter

    LAshooter Guest

    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.


     
    LAshooter, Mar 5, 2006
    #10
  11. LAshooter

    webdood Guest

    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
     
    webdood, Mar 6, 2006
    #11
  12. LAshooter

    RobG Guest

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

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

    The language attribute is deprecated, type is required.

    [...]
    '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'.

    [...]
     
    RobG, Mar 6, 2006
    #12
  13. Reliable, efficient, simple. Pick two.
    Last call for flight
    <URL:http://www.safalra.com/special/googlegroupsreply/>, gate 80,
    ladies and gentlemen!


    PointedEars
     
    Thomas 'PointedEars' Lahn, Mar 6, 2006
    #13
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.