SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Member
    Join Date
    May 2006
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Image gallery, how to display "Loading..." message while image swaps

    Hello.

    I am designing an image gallery which contains a series of links for each image which can be loaded into a central <img> tag using Javascript. As well as changing the image, a DIV which cotnains the title of the image is also changed.

    So far it works fine except that when you click to swap an image to the next one, the DIV changes instantly and the IMG only changes once the new image has downloaded. As you can image this would appear confusing to a user as the title changes but the image doesn't, at least for a while.

    What I am looking for is a way to change the title DIV to display "Loading..." until the image has been downloaded, then change the IMG and set the DIV to the image title.

    Here's the Javascript I have so far:


    Code:
        function displayImage (pic)
        {
            if (document.getElementById)
            {
                document.getElementById('imageImg').src = pic.href;
                
                if (pic.title)
                {
                    document.getElementById('imageTitleP').childNodes[0].nodeValue = pic.title;
                    document.getElementById('imageImg').title = pic.title;
                    document.getElementById('imageImg').alt = pic.title;
                }
                else
                {
                    document.getElementById('imageTitle').childNodes[0].nodeValue = 'untitled';
                    document.getElementById('imageImg').title = 'untitled';
                    document.getElementById('imageImg').alt = 'untitled';
                }
            
                return false;
            }
            else
            {
                return true;
            }
        }
    ...and the button to call the Javascript is this:


    HTML Code:
    <div class="imageButton">
        <a onclick="return displayImage(this)" href="banana.jpg" title="This is a banana">
        </a>
    </div>
    Any help would be very much appreciated - thanks!

    Nick.

  2. #2
    SitePoint Wizard chris_fuel's Avatar
    Join Date
    May 2006
    Location
    Ventura, CA
    Posts
    2,750
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    so with that in mind then:

    Code:
        function displayImage (pic)
        {
            if (document.getElementById)
            {
                if (pic.title)
                {
                    document.getElementById('imageTitleP').childNodes[0].nodeValue = pic.title;
                    document.getElementById('imageImg').title = pic.title;
                    document.getElementById('imageImg').alt = pic.title;
                }
                else
                {
                    document.getElementById('imageTitle').childNodes[0].nodeValue = 'untitled';
                    document.getElementById('imageImg').title = 'untitled';
                    document.getElementById('imageImg').alt = 'untitled';
                }
    
                document.getElementsById('imagediv').childNodes[0].nodeValue = 'Loading...';
                document.getElementById('imageImg').src = pic.href;
            
                return false;
            }
            else
            {
                return true;
            }
        }
    Also, your return logic seems off. Why would I return true if document.getElementById() doesn't exist? The point of return true is to say the function executed sucessfully.

  3. #3
    SitePoint Zealot tristanm's Avatar
    Join Date
    Jan 2005
    Location
    Hampshire, UK
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Post

    I may be missing something, but I can't for the life of me see how your script is supposed to work Chris. Could you elaborate please.

    I was trying to achieve a similar effect using the image's 'complete' property, but I could never get it to work (Javascript is not really my strong point). I've been playing around with this again this morning and settled on using the image's onload event.

    Try this:

    Code:
        function displayImage (pic)
        {
            if (document.getElementById)
            {
                var placeholder = document.getElementById('imageImg');
                var caption = document.getElementById('imageTitleP').childNodes[0];
                placeholder.src = pic.href;
                caption.nodeValue = 'Loading...'
    
                placeholder.onload = function(){
                   caption.nodeValue = pic.title;
                }                
    
                placeholder.title = pic.title;
                placeholder.alt = pic.title;
    
                return false;
            }
        }
    I haven't tested it, but it should do the job.

  4. #4
    SitePoint Member
    Join Date
    May 2006
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I actually resolved this by using the onLoad event as follows:

    Code:
    onload="document.getElementById('loading').style.visibility = 'hidden';"
    ....the only problem that remains is that the onLoad property is not valid XHTML Strict. It works, but if there was a way to get it working without the onLoad element then that would be great.

  5. #5
    SitePoint Zealot tristanm's Avatar
    Join Date
    Jan 2005
    Location
    Hampshire, UK
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by SlappyTheFish
    ....the only problem that remains is that the onLoad property is not valid XHTML Strict. It works, but if there was a way to get it working without the onLoad element then that would be great.
    Are you using all lowercase for your event handlers? Inline event handlers are legal in XHTML, but they must be lowercase i.e. "onload" as opposed to "onLoad". If you're still getting errors then post your mark-up, or a link to the page(s) in question, and I'll check it out.

  6. #6
    SitePoint Member
    Join Date
    May 2006
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello.

    Yeah, using all lowercase - here's part of the HTML:

    HTML Code:
    <div>
        <p id="loading">
            Loading...
        </p>
    </div>
    
    <div id="image">
        <img src="images/portraits/portraits/1.jpg" id="imageImg" alt="image1" title="image1" onload="document.getElementById('loading').style.visibility = 'hidden';" />
    </div>
    
    <div id="imageTitle">
        <p id="imageTitleP">
            image1
        </p>
    </div>
    
    <div id="imageMenu">
        <div class="imageButton">
            <a onclick="return displayImage(this)" href="images/portraits/portraits/1.jpg" title="image1">
            </a>
        </div>
        <div class="imageButton">
            <a onclick="return displayImage(this)" href="images/portraits/portraits/2.jpg" title="image2">
            </a>
        </div>
    </div>
    The W3 Validataor says this about onLoad:

    there is no attribute "onload".
    The Doctype declaration is as follows:

    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

  7. #7
    SitePoint Zealot tristanm's Avatar
    Join Date
    Jan 2005
    Location
    Hampshire, UK
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I stand corrected, onload is only available for the body element. From the xhtml1-strict DTD:

    Code:
    <!ENTITY % events
     "onclick     %Script;       #IMPLIED
      ondblclick  %Script;       #IMPLIED
      onmousedown %Script;       #IMPLIED
      onmouseup   %Script;       #IMPLIED
      onmouseover %Script;       #IMPLIED
      onmousemove %Script;       #IMPLIED
      onmouseout  %Script;       #IMPLIED
      onkeypress  %Script;       #IMPLIED
      onkeydown   %Script;       #IMPLIED
      onkeyup     %Script;       #IMPLIED"
      >
    
    ...
    
    <!ENTITY % attrs "%coreattrs; %i18n; %events;">
    
    ...
    
    <!ATTLIST img
      %attrs;
      src         %URI;          #REQUIRED
      alt         %Text;         #REQUIRED
      longdesc    %URI;          #IMPLIED
      height      %Length;       #IMPLIED
      width       %Length;       #IMPLIED
      usemap      %URI;          #IMPLIED
      ismap       (ismap)        #IMPLIED
      >
    To be honest, I haven't used inline event handlers for years now. Much better to attach event handlers using script. If you just want to solve the validation error, something like the following should do the job:

    Code:
    window.onload = function(){
       if (document.getElementById){
          var placeholder = document.getElementById('imageImg');
          var loading = document.getElementById('loading');
    
          placeholder.onload = function(){
             loading.style.visibility = 'hidden';
          }
       }
    }
    Again, I haven't tested it, but it should be ok.

    Of course using the "traditional" event registration model (i.e. object.event) has some important limitations, though it should be fine in your case. Check out PPK's overview of event handling in Javascript for more information.

    I assume displayImage() makes the "loading..." visible again?

  8. #8
    SitePoint Member
    Join Date
    May 2006
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great - thanks, that makes sense and seems a lot nicer than putting the onLoad inline.

    Yeah, displayImage() makes the "loading..." P visible again, but by the looks of things it should work fine with the code you posted above - I'll let you know.

    Thanks again!

  9. #9
    SitePoint Zealot tristanm's Avatar
    Join Date
    Jan 2005
    Location
    Hampshire, UK
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A slight amendment to my original function:

    Code:
     function displayImage (pic)
        {
            if (document.getElementById)
            {
                var placeholder = document.getElementById('imageImg');
                var caption = document.getElementById('imageTitleP').childNodes[0];
                
                placeholder.onload = function(){
                   caption.nodeValue = pic.title;
                }                
    
                caption.nodeValue = 'Loading...';
                placeholder.src = pic.href;
    
                placeholder.title = pic.title;
                placeholder.alt = pic.title;
    
                return false;
            }
        }
    If the image's onload event fired before the event handler was defined the caption would never change from "Loading...". Attaching the event handler before changing the caption to the loading string solves the problem.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •