Preload images

Discussion in 'Javascript' started by CK, Apr 3, 2008.

  1. CK

    CK Guest

    Hello everyone,

    I am using an image browser to select images for a website.
    Basically, it is a table showing the file name and the size, when you
    move the mouse over one image, then it gets displayed in the lower
    right corner.
    The image browser works, has done so since ages, but I noticed
    something which would explain the partly sluggish behaviour. When
    using Firefox, I see one request per image and its all good, both in
    the Firebug extention and in the access log of the Apache webserver
    behind.
    IE 6 also requests all the images, but then for each mouseover
    requests the image again.

    Well, it does not. Then I googled around for a bit and found a
    gazillion hints, most of which said "have a function in the onload
    Event-Handler and it will work".
    So I wrote a quick and dirty function which simply requests the
    images onLoad, figuring that might help.

    It does not. So, is this really an IE 6 issue or is there something I
    can do about this to make it work?
    --
    Claus Dragon <>
    =(UDIC)=
    d++ e++ T--
    K1!2!3!456!7!S a29
    "Coffee is a mocker. So, I am going to mock."

    - Me, lately.
     
    CK, Apr 3, 2008
    #1
    1. Advertising

  2. CK

    Erwin Moller Guest

    CK schreef:
    > Hello everyone,
    >
    > I am using an image browser to select images for a website.
    > Basically, it is a table showing the file name and the size, when you
    > move the mouse over one image, then it gets displayed in the lower
    > right corner.
    > The image browser works, has done so since ages, but I noticed
    > something which would explain the partly sluggish behaviour. When
    > using Firefox, I see one request per image and its all good, both in
    > the Firebug extention and in the access log of the Apache webserver
    > behind.
    > IE 6 also requests all the images, but then for each mouseover
    > requests the image again.
    >
    > Well, it does not. Then I googled around for a bit and found a
    > gazillion hints, most of which said "have a function in the onload
    > Event-Handler and it will work".
    > So I wrote a quick and dirty function which simply requests the
    > images onLoad, figuring that might help.
    >
    > It does not. So, is this really an IE 6 issue or is there something I
    > can do about this to make it work?
    > --
    > Claus Dragon <>
    > =(UDIC)=
    > d++ e++ T--
    > K1!2!3!456!7!S a29
    > "Coffee is a mocker. So, I am going to mock."
    >
    > - Me, lately.


    Hi,

    Could you show us your code for preloading, and for displaying?

    Regards,
    Erwin Moller
     
    Erwin Moller, Apr 4, 2008
    #2
    1. Advertising

  3. CK

    SAM Guest

    CK a écrit :
    > Hello everyone,
    >
    > I am using an image browser to select images for a website.
    > Basically, it is a table showing the file name and the size, when you
    > move the mouse over one image, then it gets displayed in the lower
    > right corner.


    Is it something like :

    <p id="smallImgs">
    <img src="photo_1.jpg" onmouseover"viewer.src=this.src" alt="">
    <img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
    <img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
    </p>
    <img name="viewer" src="empty.gif" alt=="">

    Or do you use thumbnalis and associated big images ?

    > IE 6 also requests all the images, but then for each mouseover
    > requests the image again.


    Idea for a gallery of images :

    <script type="text/javascript">

    var P = ['dod','cat','cow'], // array of images to display later
    fold = 'album_1/', // folder of images
    k = 0,
    I = [] ;
    function cacheImg() { // put in cache paths of images
    if(k<P.length) {
    var F = true;
    I[k] = new Image();
    // if possible force the image in the cache
    if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
    I[k].src = fold + P[k] + '.jpg';
    k++
    if(F) cacheImg();
    }
    else reveal();
    }
    function reveal() {
    document.getElementById('wait').style.display='none';
    document.getElementById('album').style.display='block';
    }
    function browse(num) {
    document.images['viewer'].src = I[num].src;
    }

    window.onload = cacheImg;

    </script>
    </head>
    <body>
    <p id="wait">Please wait images loading <img src="wait.gif" alt=""></p>
    <p style="display:none" id="album">
    <a href="javascript:browse(0)">view 1</a>
    <a href="javascript:browse(1)">view 2</a>
    <a href="javascript:browse(2)">view 3</a>
    </p>
    <img name="viewer" src="vide.gif" alt="">



    --
    sm
     
    SAM, Apr 4, 2008
    #3
  4. CK

    Snorik Guest

    Hello,

    sure, here is the Javascript code:

    var freeze = 0;
    function datacapture_get_content()
    {
    var data = '';
    var calloutForm =
    eval(window.opener.top.getDCFrame(window.opener).formframe.document.dcreditForm);
    if (!calloutForm)
    {
    alert('Fatal callout error. Did you close the datacapture
    window?');
    }
    var calloutElementFound = false;
    for ( i = 0 ; i < calloutForm.elements.length ; i++ )
    {
    if (calloutForm.elements.name == 'catalog_update_content/
    catalog_thumbnail_FBA')
    {
    data = calloutForm.elements.value ;
    calloutElementFound = true ;
    break;
    }
    }
    return data;
    }

    function datacapture_callback( data )
    {
    var calloutForm =
    eval(window.opener.top.getDCFrame(window.opener).formframe.document.dcreditForm);
    if (!calloutForm)
    {
    alert('Fatal callout error. Did you close the datacapture
    window?');
    }
    var calloutElementFound = false;
    for ( i = 0 ; i < calloutForm.elements.length ; i++ )
    {
    if (calloutForm.elements.name == 'catalog_update_content/
    catalog_thumbnail_FBA')
    {
    calloutForm.elements.value = data ;
    calloutElementFound = true ;
    break;
    }
    }
    if(opener.top.datacapture) {
    opener.top.datacapture.refreshForm();
    }
    self.close();
    }

    function set_content()
    {
    var fba = document.form.fba.value;
    if (!fba)
    {
    alert('Please select one file');
    }
    else
    {
    datacapture_callback(fba);
    }

    }
    function set_dir( data )
    {
    freeze = 1 ;
    document.form.dir.value = data;
    document.form.files_view.value = '0';
    document.form.submit();

    }
    function set_file( value, data )
    {
    document.forms[0].fba.value = value;
    if (freeze == 0)
    {
    freeze = 1 ;
    }
    else
    {
    freeze = 0 ;
    document.images['imageboard'].src = ts_image[data].src;
    document.images['imageboard'].width = ts_image[data].width;
    document.images['imageboard'].height = ts_image[data].height;
    document.forms[0].name.value = ts_image[data].name;
    document.forms[0].size.value = ts_image[data].size;
    }
    }

    function show_image( data ) {
    if (freeze == 0) {
    document.images['imageboard'].src = ts_image[data].src;
    document.images['imageboard'].width = ts_image[data].width;
    document.images['imageboard'].height = ts_image[data].height;
    document.forms[0].name.value = ts_image[data].name;
    document.forms[0].size.value = ts_image[data].size;
    }
    }

    function show_no_image(data) {
    if (freeze == 0) {
    document.images['imageboard'].src = '/iw/images/c.gif';
    document.images['imageboard'].width = '';
    document.images['imageboard'].height = '';
    document.forms[0].name.value = ts_image[data].name;
    document.forms[0].size.value = ts_image[data].size;
    }
    }

    function set_view( data )
    {
    document.form.view.value = data;
    document.form.dir.value = '';
    document.form.files_view.value = '0';
    document.form.submit();

    }
    function set_file_view( data )
    {
    document.form.files_view.value = data;
    document.form.submit();
    }

    ts_image = new Array( 13 );
    ts_image[12] = new Image(300,199);
    ts_image[12].src = '/images_path/image1.jpg';
    ts_image[12].width = '300';
    ts_image[12].height = '199';
    ts_image[12].name = 'filename : image1.jpg';
    ts_image[12].size = 'filesize : 612 x 406';
    ts_image[10] = new Image(102,72);
    ts_image[10].src = '/images_path/image2.jpg';
    ts_image[10].width = '102';
    ts_image[10].height = '72';
    ts_image[10].name = 'filename : image2.jpg';
    ts_image[10].size = 'filesize : 102 x 72';

    // removed additional entries, I think you get the picture


    // basically redundant function for the body tag onLoad event trigger,
    to try out whether that helps with IE 6
    //it does not really help. Yes, I know, it simply doubles the
    requests, as the images are already loaded, at least for FireFox.
    function loadImages(){
    images = new Array( 13 );
    images[12] = '/images_path/image1.jpg';
    images[10] = '/images_path/image2.jpg';
    //again, additional values removed
    }

    <!-- here is the code in the body -->

    <body onload="loadImages()">
    <!-- [...] -->

    <!-- the actual table: -->

    <table class="heading" height="25" border="0" width="100%">
    <tr>
    <td class="heading-title">Image browser</td>
    <td class="heading-user" align="right">user:&nbsp <i>user</i></td>
    </tr>
    </table>
    <form method="get" id="form" name="form">
    <div style="width:600px; height:22px; border:1px solid #840; border-
    bottom: 0px; background-color: #eeeeee; margin-left:1em; margin-top:
    0.8em;">
    &nbsp;
    <font color='#666666' style='font-size:11px'>local:&nbsp;</font>
    <!-- woops, here is a table start missing -->
    <tr style='background-color: #ddeeff;' >
    <td align='left' width='5px'>
    <img src="/file_images/img_file.gif" alt="dir" height="15"
    border="0" />
    </td>
    <td>
    <a href='javascript:set_file("/images_path/image1.jpg", "0");'
    onDbClick='set_content();' onmouseover='show_image( 0 );'>
    image1.jpg
    </a>
    </td>
    <td style='font-size: 11px;'>
    (277 x 184)
    </td>
    <td style=' font-size: 11px;'>
    15 kb
    </td>
    </tr>

    <!-- and so on ... -->

    I have removed some of the values in order not to have a boring list
    of array entries.
    Is there anything in there which could possibly make IE not use the
    cached images?

    Thanks for your time,

    Claus
     
    Snorik, Apr 4, 2008
    #4
  5. CK

    Snorik Guest

    On 4 Apr., 10:16, SAM <>
    wrote:
    > CK a écrit :
    >
    > > Hello everyone,

    >
    > > I am using an image browser to select images for a website.
    > > Basically, it is a table showing the file name and the size, when you
    > > move the mouse over one image, then it gets displayed in the lower
    > > right corner.

    >
    > Is it something like :
    >
    > <p id="smallImgs">
    > <img src="photo_1.jpg" onmouseover"viewer.src=this.src" alt="">
    > <img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
    > <img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
    > </p>
    > <img name="viewer" src="empty.gif" alt=="">
    >
    > Or do you use thumbnalis and associated big images ?


    Perl::ImageMagick creates thumbnails to fit into the image area.


    > Idea for a gallery of images :
    >
    > <script type="text/javascript">
    >
    > var P = ['dod','cat','cow'], // array of images to display later
    > fold = 'album_1/', // folder of images
    > k = 0,
    > I = [] ;
    > function cacheImg() { // put in cache paths of images
    > if(k<P.length) {
    > var F = true;
    > I[k] = new Image();
    > // if possible force the image in the cache
    > if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
    > I[k].src = fold + P[k] + '.jpg';
    > k++
    > if(F) cacheImg();
    > }
    > else reveal();}


    How does this work? If the image in question is not in the cache
    array, then load the object on load by the function? I already use an
    array to store the images, two in fact (one being redundant, see other
    post).

    Regards,
    Claus
     
    Snorik, Apr 4, 2008
    #5
  6. CK

    SAM Guest

    Snorik a écrit :
    > On 4 Apr., 10:16, SAM <>
    > wrote:
    >
    >> Idea for a gallery of images :
    >>
    >> <script type="text/javascript">
    >>
    >> var P = ['dod','cat','cow'], // array of images to display later
    >> fold = 'album_1/', // folder of images
    >> k = 0,
    >> I = [] ;
    >> function cacheImg() { // put in cache paths of images
    >> if(k<P.length) {
    >> var F = true;
    >> I[k] = new Image();
    >> // if possible force the image in the cache
    >> if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
    >> I[k].src = fold + P[k] + '.jpg';
    >> k++
    >> if(F) cacheImg();
    >> }
    >> else reveal();}

    >
    > How does this work? If the image in question is not in the cache


    doing a JS in the head like

    var a = new Image(); a.src='img_1.jpg';
    var b = new Image(); b.src='img_2.jpg';

    both images are supposed to be sent in the cache


    If they are not yet
    (because you dind't leave time to time or any other reason),
    no importance.
    Calling the image by its JS src will load the right image,
    a.src being only the path to the image (on server).

    But, on next call of a.src,
    this time we surely get the image from cache.

    --
    sm
     
    SAM, Apr 4, 2008
    #6
  7. CK

    Henry Guest

    On Apr 4, 1:21 pm, SAM wrote:
    <snip>
    > doing a JS in the head like
    >
    > var a = new Image(); a.src='img_1.jpg';
    > var b = new Image(); b.src='img_2.jpg';
    >
    > both images are supposed to be sent in the cache


    Says who?

    > If they are not yet
    > (because you dind't leave time to time or any other reason),
    > no importance.
    > Calling the image by its JS src will load the right image,
    > a.src being only the path to the image (on server).
    >
    > But, on next call of a.src,


    You are disregarding the influence of HTTP caching (and caching
    influencing) headers and browser configuration. If the browser is
    configured to re-retrieved for each request that is what it will do,
    and if the HTTP headers assert that the image is not to be cached the
    odds are good that it will not be, and if they assert that any
    previously cached resource has expired it should be re-retrieved
    regardless of whether it is in the cache or not.
     
    Henry, Apr 4, 2008
    #7
  8. CK

    SAM Guest

    Henry a écrit :
    > On Apr 4, 1:21 pm, SAM wrote:
    > <snip>
    >> doing a JS in the head like
    >>
    >> var a = new Image(); a.src='img_1.jpg';
    >> var b = new Image(); b.src='img_2.jpg';
    >>
    >> both images are supposed to be sent in the cache

    >
    > Says who?


    Not me.
    (Rarely I've seen that really working on 1srt pass)

    >> If they are not yet
    >> (because you dind't leave time to time or any other reason),
    >> no importance.
    >> Calling the image by its JS src will load the right image,
    >> a.src being only the path to the image (on server).
    >>
    >> But, on next call of a.src,

    >
    > You are disregarding the influence of HTTP caching


    Yes, absolutely, and it's a good remark.
    I hope all is OK to do what this JS is supposed to do.

    I can't fix all the configurations from my chair :)


    --
    sm
     
    SAM, Apr 4, 2008
    #8
  9. CK

    Snorik Guest

    On 4 Apr., 14:21, SAM <>
    wrote:
    > Snorik a écrit :
    >
    >
    >
    > > On 4 Apr., 10:16, SAM <>
    > > wrote:

    >
    > >> Idea for a gallery of images :

    >
    > >> <script type="text/javascript">

    >
    > >> var P = ['dod','cat','cow'], // array of images to display later
    > >> fold = 'album_1/', // folder of images
    > >> k = 0,
    > >> I = [] ;
    > >> function cacheImg() { // put in cache paths of images
    > >> if(k<P.length) {
    > >> var F = true;
    > >> I[k] = new Image();
    > >> // if possible force the image in the cache
    > >> if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
    > >> I[k].src = fold + P[k] + '.jpg';
    > >> k++
    > >> if(F) cacheImg();
    > >> }
    > >> else reveal();}

    >
    > > How does this work? If the image in question is not in the cache

    >
    > doing a JS in the head like
    >
    > var a = new Image(); a.src='img_1.jpg';
    > var b = new Image(); b.src='img_2.jpg';
    >
    > both images are supposed to be sent in the cache


    Ok, but am I not doing that already via the array(s)?

    > If they are not yet
    > (because you dind't leave time to time or any other reason),
    > no importance.
    > Calling the image by its JS src will load the right image,
    > a.src being only the path to the image (on server).


    OK.
     
    Snorik, Apr 4, 2008
    #9
  10. CK

    Snorik Guest

    On 4 Apr., 14:46, Henry <> wrote:

    > You are disregarding the influence of HTTP caching (and caching
    > influencing) headers and browser configuration. If the browser is
    > configured to re-retrieved for each request that is what it will do,
    > and if the HTTP headers assert that the image is not to be cached the
    > odds are good that it will not be, and if they assert that any
    > previously cached resource has expired it should be re-retrieved
    > regardless of whether it is in the cache or not.


    Silly question but where do I see that? Live HTTP headers does not
    show any expiry-date, at least none I can recognize...
    Also, where in that trice-%&§! IE can I toggle that?
     
    Snorik, Apr 4, 2008
    #10
  11. CK

    SAM Guest

    Snorik a écrit :
    > On 4 Apr., 14:21, SAM <>
    > wrote:
    >>
    >> doing a JS in the head like
    >>
    >> var a = new Image(); a.src='img_1.jpg';
    >> var b = new Image(); b.src='img_2.jpg';
    >>
    >> both images are supposed to be sent in the cache

    >
    > Ok, but am I not doing that already via the array(s)?


    I'm a little lost in your fat code ;-)

    Where are the src of new images ?

    here ? :

    ts_image = new Array( 13 );
    ts_image[12] = new Image(300,199);
    ts_image[12].src = '/images_path/image1.jpg';
    ts_image[12].width = '300';
    ts_image[12].height = '199';
    ts_image[12].name = 'filename : image1.jpg';
    ts_image[12].size = 'filesize : 612 x 406';

    what could be the use of width, height, size ?


    or here ? :

    function loadImages(){
    images = new Array( 13 );
    images[12] = '/images_path/image1.jpg';
    images[10] = '/images_path/image2.jpg';
    //again, additional values removed
    }
    where I see no 'src' ...


    Try :

    var images = new Array(); // except if you use it in a loop
    // you don't need the number of images

    function loadImages(){
    images[12] = new Image();
    images[12].src = '/images_path/image1.jpg';
    images[11] = new Image();
    images[11].src = '/images_path/image2.jpg';
    //again, additional values removed
    }

    and this function could be good for all navigators


    Your biggest problem is that you want to change images on a mouseover
    and in most of cases the new image to display is still on the server, so
    user will have to be patient.
    The second point is that the browser, on each call to one image, will go
    to see on server if the image to display is the same as this in its cache.

    Then ... I do not understand the utility of this funtion 'loadImages'
    and its array 'images' when to display a new image you use the array
    'ts_image' here :

    function show_image( data ) {
    if (freeze == 0) {
    document.images['imageboard'].src = ts_image[data].src;
    document.forms[0].name.value = ts_image[data].name;
    document.forms[0].size.value = ts_image[data].size;
    }

    --
    sm
     
    SAM, Apr 4, 2008
    #11
  12. CK

    CK Guest

    Words to the wise, SAM <>
    wrote:

    >Snorik a écrit :
    >> On 4 Apr., 14:21, SAM <>
    >> wrote:
    >>>
    >>> doing a JS in the head like
    >>>
    >>> var a = new Image(); a.src='img_1.jpg';
    >>> var b = new Image(); b.src='img_2.jpg';
    >>>
    >>> both images are supposed to be sent in the cache

    >>
    >> Ok, but am I not doing that already via the array(s)?

    >
    >I'm a little lost in your fat code ;-)
    >
    >Where are the src of new images ?
    >
    >here ? :
    >
    >ts_image = new Array( 13 );
    > ts_image[12] = new Image(300,199);
    > ts_image[12].src = '/images_path/image1.jpg';
    > ts_image[12].width = '300';
    > ts_image[12].height = '199';
    > ts_image[12].name = 'filename : image1.jpg';
    > ts_image[12].size = 'filesize : 612 x 406';
    >
    >what could be the use of width, height, size ?


    Those are being used for ImageMagick.

    >or here ? :
    >
    >function loadImages(){
    >images = new Array( 13 );
    >images[12] = '/images_path/image1.jpg';
    >images[10] = '/images_path/image2.jpg';
    >//again, additional values removed
    >}
    >where I see no 'src' ...


    Ok, my mistake, completely forgot about that.

    >
    >Try :
    >
    >var images = new Array(); // except if you use it in a loop
    > // you don't need the number of images
    >
    >function loadImages(){
    > images[12] = new Image();
    > images[12].src = '/images_path/image1.jpg';
    > images[11] = new Image();
    > images[11].src = '/images_path/image2.jpg';
    >//again, additional values removed
    >}
    >
    >and this function could be good for all navigators


    Ok, I will try that out and post some results.

    >Your biggest problem is that you want to change images on a mouseover
    >and in most of cases the new image to display is still on the server, so
    >user will have to be patient.
    >The second point is that the browser, on each call to one image, will go
    >to see on server if the image to display is the same as this in its cache.
    >
    >Then ... I do not understand the utility of this funtion 'loadImages'
    >and its array 'images' when to display a new image you use the array
    >'ts_image' here :


    I had just added the loadImages() function in order to check whether
    taking advantage of the onload event handler had any impact.

    --
    Claus Dragon <>
    =(UDIC)=
    d++ e++ T--
    K1!2!3!456!7!S a29
    "Coffee is a mocker. So, I am going to mock."

    - Me, lately.
     
    CK, Apr 4, 2008
    #12
  13. CK

    SAM Guest

    CK a écrit :
    >
    > I had just added the loadImages() function in order to check whether
    > taking advantage of the onload event handler had any impact.


    I didn't see in details all your lines of code but if you don't call the
    array 'images' (foo.src = images[number].src) there is no advantage than
    to give some more work to the browser.

    Difference I see between to give directly the array of new images (and
    their src) in the head and by a function on loading (after loaded) is :
    - in head it is supposed that new images (or at least their path : src)
    are put in cache "before" full loading
    - body onload : caching only "after" the page is loaded (displayed)
    but ... as soon as user begins to click the page I think this
    'loadImages' is stopped (or at least paused)

    The first way (if it works : images loaded and in cache) is, on my idea,
    not good for user who will can have to wait with a white screen all big
    images. (usually only paths are memorized for a possible re-using and
    that takes no time)
    The 2nd allows the page to load normally.

    In my youngness most of browsers accepted the function 'onload'
    attributed to images (and by the fact attributed to JS new images).
    With this feature it was possible to be sure to get them in cache (if
    correctly fixed HTTP headers and so on)

    var Imgs = new Array();
    var fold = 'album_1/';
    var Views = new Array(13);
    var n = 0;
    function postLoad() {
    if(n < Views.length) {
    Imgs[n] = new Image();
    Imgs[n].onload = postLoad; // when img 'n' loaded go to load next one
    Ims[n].src = fold + 'photo_' + n + '.jpg';
    n++
    }
    }

    Seems to do no more work with my Safari, Opera and IE6
    ( image.onload is not a function for them)
    Only my Fx supports that.



    Possibility (not tested) to post-load images :

    CSS :
    =====
    #stock { position: absolute; margin-left: -2000px; width: 1500px }
    #stock img { position: absolute; top:0; left: 0;}

    JS :
    ====
    var Imgs = new Array(),
    num = 13,
    fold = 'album_1/';
    window.onload = function() {
    for(var i=0; i<num; i++) {
    Imgs[n] = new Image();
    Imgs[n].src = fold+n+'.jpg';
    createImg(n).src = Imgs[n].src;
    }
    }
    function createImg(n) {
    var I = document.createElement('IMG');
    I.id = 'S_'+n;
    document.getElementById('stock').appendChild(I);
    return I;
    }
    function showImg(num) {
    var viewScreen = document.getElementById('viewer');
    if(document.getElementById('S_'+num)) {
    var I = document.getElementById('S_'+num);
    var f = document.forms[0];
    viewScreen.src = I.src;
    f[0].value = I.width;
    f[1].value = I.height;
    }
    else
    viewScreen.src = Imgs[n].src;
    }

    html :
    ======
    <div id="stock"></div>
    <p><a href="javascript:showImg(0)">view 1</a>
    <a href="javascript:showImg(1)">view 2</a>
    <a href="javascript:showImg(2)">view 3</a></p>
    <form>
    Image width: <input>, image height: <input>
    <img id="viewer" src="empty.gif" alt="">
    </form>

    With a little bit of luck perhaps that could +/- work ?

    --
    sm
     
    SAM, Apr 5, 2008
    #13
  14. CK

    Snorik Guest

    On 5 Apr., 01:02, SAM <>
    wrote:
    > CK a écrit :
    >
    >
    >
    > > I had just added the loadImages() function in order to check whether
    > > taking advantage of the onload event handler had any impact.

    >
    > I didn't see in details all your lines of code but if you don't call the
    > array 'images' (foo.src = images[number].src) there is no advantage than
    > to give some more work to the browser.


    Ok, I changed that. Now there is only one array of images which looks
    like the following:


    function loadImages()
    {
    [...]
    ts_image = new Array( 13 );
    ts_image[12] = new Image(300,199);
    ts_image[12].src = '/path/image';
    ts_image[12].width = '300';
    ts_image[12].height = '199';
    ts_image[12].name = 'filename : image';
    ts_image[12].size = 'filesize : 612 x 406';
    [other values removed due to avoid clutter]
    }

    function show_image( data ) {
    if (freeze == 0) {
    document.images['imageboard'].src = ts_image[data].src;
    document.images['imageboard'].width = ts_image[data].width;
    document.images['imageboard'].height = ts_image[data].height;
    document.forms[0].name.value = ts_image[data].name;
    document.forms[0].size.value = ts_image[data].size;
    }
    }

    one of the list items:

    <tr >
    <td align='left' width='5px'>
    <img src="img_file.gif" alt="dir" height="15" border="0" />
    </td><td>
    <a href='javascript:set_file("path/image.jpg", "11");'
    onDbClick='set_content();' onmouseover='show_image( 11 );'>
    image
    </a>
    </td>
    <td style='font-size: 11px;'>

    (277 x 184)
    </td>
    <td style=' font-size: 11px;'>
    15 kb
    </td>
    </tr>


    The img tag where the images are being shown:

    <td valign='top' align='center'>
    <img name='imageboard' width='300' height='210' border='0' src='path/
    image'>
    </td>


    > Difference I see between to give directly the array of new images (and
    > their src) in the head and by a function on loading (after loaded) is :
    > - in head it is supposed that new images (or at least their path : src)
    > are put in cache "before" full loading
    > - body onload : caching only "after" the page is loaded (displayed)
    > but ... as soon as user begins to click the page I think this
    > 'loadImages' is stopped (or at least paused)
    >
    > The first way (if it works : images loaded and in cache) is, on my idea,
    > not good for user who will can have to wait with a white screen all big
    > images. (usually only paths are memorized for a possible re-using and
    > that takes no time)
    > The 2nd allows the page to load normally.


    Ok, the second approach sounds more reasonable anyways.

    *snip*

    > Seems to do no more work with my Safari, Opera and IE6
    > ( image.onload is not a function for them)
    > Only my Fx supports that.


    It is working in Ffx anyways, its just IE which is getting on my
    nerves.

    Still does not work for IE. I also tried to use the document.images[n]
    object, figuring that those images should be in cache as they are in
    the document which is completely loaded, but it is a bit hard to find
    out which image of my array lands in what position of that array. Is
    there an easy way to check this, apart from iterating over the
    document.images (for i=0, ...) {if document.images..src =
    ts_image.src } ?


    Cheers.
     
    Snorik, Apr 8, 2008
    #14
  15. Snorik wrote:
    > [...] SAM [...] wrote:
    >> CK a écrit :
    >>> I had just added the loadImages() function in order to check whether
    >>> taking advantage of the onload event handler had any impact.

    >> I didn't see in details all your lines of code but if you don't call the
    >> array 'images' (foo.src = images[number].src) there is no advantage than
    >> to give some more work to the browser.

    >
    > Ok, I changed that. Now there is only one array of images which looks
    > like the following:
    >
    > function loadImages()
    > {
    > [...]
    > ts_image = new Array( 13 );


    Since you don't appear to use ts_image.length, the `13' argument is
    unnecessary and potentially harmful (not because it's this particular number).

    > ts_image[12] = new Image(300,199);


    The arguments are unnecessary.

    > ts_image[12].src = '/path/image';


    OK.

    > ts_image[12].width = '300';
    > ts_image[12].height = '199';


    Those properties expect number values, not strings. Besides, they would
    have been set already with the constructor arguments, which is what they are
    for.

    > ts_image[12].name = 'filename : image';


    `Image' objects are host objects, they do not need to be supported, and if
    they are, they do not need to support the augmentation with properties.

    `Image' objects don't have a `name' property by default, and even if they do
    implement the HTMLImageElement interface of W3C DOM Level 2 HTML, the `name'
    property would require a NAME value, which must not contain whitespace or `:'.

    > ts_image[12].size = 'filesize : 612 x 406';


    Same here. Besides, the image dimensions are _not_ the file size.

    You should use something like the following:

    function getImage(s, fLoad, fError)
    {
    var img = new Image();
    img.src = s;

    if (typeof fLoad == "function"
    && typeof img.onload != "undefined")
    {
    img.onload = fLoad;
    }

    if (typeof fError == "function"
    && typeof img.onerror != "undefined")
    {
    img.onerror = fError;
    }
    }

    var ts_image = new Array(
    getImage('/path/image')
    );

    (or

    var ts_image = new Array();
    ts_image[12] = getImage('/path/image');

    but there is little point in that although it works.)

    The rest can follow from the `width', `height', and `src' properties that
    the object has already; you do not have to duplicate that information, but
    you can write a wrapper object that allows it to be retrieved easily in the
    desired form:

    function MyImage(s)
    {
    this.setImage(s);
    }

    MyImage.prototype = {
    constructor: MyImage,

    setImage: function(s) {
    this.data = getImage(s);
    this.filename = s;
    },

    getNameStr: function() {
    return "filename: image";
    },

    getDimensions: function() {
    return "dimensions: " + this.data.width + " x " + this.data.height;
    }
    };

    var ts_image = new Array(
    new MyImage('/path/image')
    );

    // note the timing issue
    window.alert(ts_image[0].getDimensions);

    > [...]
    > function show_image( data ) {
    > if (freeze == 0) {


    Where does `freeze' come from? Avoid global variables.

    > document.images['imageboard'].src = ts_image[data].src;
    > document.images['imageboard'].width = ts_image[data].width;
    > document.images['imageboard'].height = ts_image[data].height;


    This is quite inefficient. Consider this:

    var imgTarget = document.images['imageboard'];
    var imgSource = ts_image[data];

    imgTarget.src = imgSource.src;
    imgTarget.width = imgSource.width;
    imgTarget.height = imgSource.height;

    One could even consider

    with (imgSource)
    {
    imgTarget.src = src;
    imgTarget.width = width;
    imgTarget.height = height;
    }

    > document.forms[0].name.value = ts_image[data].name;
    > document.forms[0].size.value = ts_image[data].size;


    Same here. You should avoid such reference worms, they are not only
    inefficient, but also error-prone and hard to maintain.

    > [...] }
    > }
    >
    > one of the list items:
    >


    [reformatted; use spaces for indentation, not tabs]
    > <tr>
    > <td align='left' width='5px'>
    > <img src="img_file.gif" alt="dir" height="15" border="0" />

    ^
    It can be only either HTML or XHTML. I suggest you use the former, also
    because you use camel-cased attribute names already which is not allowed in
    XHTML.

    > </td><td>
    > <a href='javascript:set_file("path/image.jpg", "11");'
    > onDbClick='set_content();' onmouseover='show_image( 11 );'>

    ^^^
    Typo.

    > image


    Avoid whitespace after inner start tags and before inner end tags, it is not
    uniformly displayed.

    > </a>


    If a widget works only with enabled script-support, you should generate it
    with scripting to save other users and yourself the hassle of dealing with a
    widget "not working":

    <script type="text/javascript">
    document.write(
    '<a href=\'javascript:set_file('
    + '"path/image.jpg", "11");\' ondblclick="set_content();"'
    + ' onmouseover="show_image(11);">image<\/a>'
    );
    </script>

    That said, you should avoid such widgets in the first place. For example, a
    submit button can provide for functionality that degrades gracefully here.

    > [...]
    > The img tag where the images are being shown:


    There are no "img tags". There are `img' elements, and <img ...> start tags.

    > [...]



    HTH

    PointedEars
    --
    Prototype.js was written by people who don't know javascript for people
    who don't know javascript. People who don't know javascript are not
    the best source of advice on designing systems that use javascript.
    -- Richard Cornford, cljs, <f806at$ail$1$>
     
    Thomas 'PointedEars' Lahn, Apr 8, 2008
    #15
  16. Thomas 'PointedEars' Lahn wrote:
    > [...]
    > var ts_image = new Array(
    > new MyImage('/path/image')
    > );
    >
    > // note the timing issue
    > window.alert(ts_image[0].getDimensions);


    Race conditions aside, don't forget to call it :)

    window.alert(ts_image[0].getDimensions());


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
     
    Thomas 'PointedEars' Lahn, Apr 8, 2008
    #16
  17. CK

    SAM Guest

    Snorik a écrit :
    > On 5 Apr., 01:02, SAM <>
    > wrote:
    >> The 2nd allows the page to load normally.

    >
    > Ok, the second approach sounds more reasonable anyways.
    >
    >> Seems to do no more work with my Safari, Opera and IE6
    >> ( image.onload is not a function for them)
    >> Only my Fx supports that.

    >
    > It is working in Ffx anyways, its just IE which is getting on my
    > nerves.


    With IE you can try to load each image at place of another one (this
    last one being positioned outside ot the window)


    HTML :
    ======
    <img src="#" style="position:absolute;margin-left:-2000px;left:-2000px"
    name="IE" alt="false image" onload="loadIncache()">
    <h2 style="color:red">Images loading : <span id="wait"></span></h2>

    JS :
    ====
    var idx = 0;
    function loadInCache() {
    if(idx < ts_image.length) {
    document.IE.src = ts_image[idx].src;
    document.getElementById('wait').innerHTML += 'X';
    idx++
    }
    else
    document.getElementById('wait').innerHTML = 'no more image';
    }
    window.onload = function() {
    loadImages();
    loadInCache();
    }




    Absolutely not tested !
    In fact that works with Safari
    but I've got a problem : my IE6 doesn't see : window.onload :-(

    --
    sm
     
    SAM, Apr 8, 2008
    #17
  18. CK

    CK Guest

    Words to the wise, Thomas 'PointedEars' Lahn <>
    wrote:
    *snip before*

    Ok, thanks for the hints and pointers on that part so far, I will use
    your suggestions.

    >[reformatted; use spaces for indentation, not tabs]
    >> <tr>
    >> <td align='left' width='5px'>
    >> <img src="img_file.gif" alt="dir" height="15" border="0" />

    > ^
    >It can be only either HTML or XHTML. I suggest you use the former, also
    >because you use camel-cased attribute names already which is not allowed in
    >XHTML.


    What do you mean with "camel-cased"?

    *snip further two suggestions which will be implemented*

    >If a widget works only with enabled script-support, you should generate it
    >with scripting to save other users and yourself the hassle of dealing with a
    >widget "not working":


    Could you please explain this a bit further?

    *snip code*

    >That said, you should avoid such widgets in the first place. For example, a
    >submit button can provide for functionality that degrades gracefully here.


    Oh, there is a submit button there for submitting the selection. The
    whole problem is getting IE not to request each image for each
    mouseover.

    Is there an AJAX way to check when a request is currently on its way
    and until that is finished not execute the next request on a special
    event handler (mouseover in this case)?

    >> [...]
    >> The img tag where the images are being shown:

    >
    >There are no "img tags". There are `img' elements, and <img ...> start tags.


    Ok, I fell into that pit, serves me right, I guess.

    Thanks for your help.
    --
    Claus Dragon <>
    =(UDIC)=
    d++ e++ T--
    K1!2!3!456!7!S a29
    "Coffee is a mocker. So, I am going to mock."

    - Me, lately.
     
    CK, Apr 8, 2008
    #18
  19. CK

    SAM Guest

    Thomas 'PointedEars' Lahn a écrit :
    >
    > You should use something like the following:
    >
    > function getImage(s, fLoad, fError)
    > {
    > var img = new Image();
    > img.src = s;
    >
    > if (typeof fLoad == "function"
    > && typeof img.onload != "undefined")


    My Safari thinks it's an 'object'
    My Firefox thinks it's 'undefined'

    > {
    > img.onload = fLoad;


    That works with my Firefox(*) and not with my Safari

    (*) if typeof img.onload != 'object'

    > }
    >
    > if (typeof fError == "function"
    > && typeof img.onerror != "undefined")
    > {
    > img.onerror = fError;
    > }
    > }
    >
    > var ts_image = new Array(
    > getImage('/path/image')
    > );


    --
    sm
     
    SAM, Apr 8, 2008
    #19
  20. CK wrote:
    > Words to the wise, Thomas 'PointedEars' Lahn <>
    > wrote:
    > *snip before*
    >
    > Ok, thanks for the hints and pointers on that part so far, I will use
    > your suggestions.


    You're welcome.

    >> [reformatted; use spaces for indentation, not tabs]
    >>> <tr>
    >>> <td align='left' width='5px'>
    >>> <img src="img_file.gif" alt="dir" height="15" border="0" />

    >> ^
    >> It can be only either HTML or XHTML. I suggest you use the former, also
    >> because you use camel-cased attribute names already which is not allowed in
    >> XHTML.

    >
    > What do you mean with "camel-cased"?


    In this case: mixing uppercase and lowercase characters.

    http://en.wikipedia.org/wiki/CamelCase

    You should use only lowercase letters for element type/element/attribute
    names and IDs instead, not only because XHTML demands it for element types
    and attribute names (and so either it is a requirement for Valid/working
    markup, or a future transition will be easier), but also because turns out
    to be easier to maintain [think of search and replace, and of DOM access],
    and to be better compressible (lowercase characters have a greater
    probability than uppercase characters in a standard latin text).

    >> If a widget works only with enabled script-support, you should generate it
    >> with scripting to save other users and yourself the hassle of dealing with a
    >> widget "not working":

    >
    > Could you please explain this a bit further?


    Gladly.

    Users of an environment where client-side script support is not available
    will complain to you (or your customer who owns the site) or silently go
    away because either nothing happens if a widget is activated or in your case
    it may very well cause an error message then. If they complain, you (or
    your customer) will have to deal with the complaints (which can affect your
    reputation in a negative way). In any case, you (or your customer) will
    have to deal with your shrinking/comparably small user base (you'll/they'll
    ask yourself/themselves: Why are some of my competitors this much more
    successful?)

    It is a key feature of a good Web site/application, and a legal requirement
    in some environments/countries, to be accessible, to degrade gracefully if a
    used technology is not available, including client-side scripting. One
    important reason for that, but by far not the only one, is that studies have
    shown people with disabilities to use the Internet (and the Web)
    proportionally more than other people -- guess why.

    >> That said, you should avoid such widgets in the first place. For example, a
    >> submit button can provide for functionality that degrades gracefully here.

    >
    > Oh, there is a submit button there for submitting the selection. The
    > whole problem is getting IE not to request each image for each
    > mouseover.


    Pardon, I just jumped into the thread, observing the (to me) obvious
    mistakes in your code.

    The problem you describe exists with other user agents as well, and
    preloading as you are trying can help here, but it does not have to. The
    cache of the user's user agent is solely under the control of the user,
    not the Web developer. In the worst case, the image will be downloaded
    twice at least. This is not to recommend foregoing the idea completely,
    you should just be aware of it.

    > Is there an AJAX way to check when a request is currently on its way
    > and until that is finished not execute the next request on a special
    > event handler (mouseover in this case)?


    ("AJAX" is a misnomer. s/AJAX/XMLHttpRequest (XHR)/g)

    Not really. You would have to request the data through XHR then, and then
    you would have the problem to use the response body to generate an image
    (`javascript:' and `data:' URIs can help out here, but they do not have to).


    Your (quite interesting) .sig is a bit long, try to reduce it to 4 lines
    (not counting the delimiter). Also, the delimiter is broken; it has to be
    "-- <CR><LF>".

    I am a bit confused about your "From" header, probably I'm not the only one.
    It is better to post only under one name in Usenet in order to avoid
    confusion and to be recognized, preferably your real one (as you can see,
    the nickname can also be included easily).


    Regards,

    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
     
    Thomas 'PointedEars' Lahn, Apr 8, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Morris

    preload images

    Morris, Nov 12, 2003, in forum: HTML
    Replies:
    5
    Views:
    616
    Beauregard T. Shagnasty
    Nov 14, 2003
  2. ks
    Replies:
    1
    Views:
    380
    Mark Rae
    Aug 5, 2006
  3. shapper
    Replies:
    4
    Views:
    4,072
    Laurent Bugnion
    Nov 25, 2006
  4. =?Utf-8?B?Q2FzcGE=?=

    Preload images returned by an HttpHandler

    =?Utf-8?B?Q2FzcGE=?=, Mar 9, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    400
    Chilumba Mubashi [MSFT]
    Mar 28, 2007
  5. Mark

    Preload TreeView images

    Mark, Feb 13, 2004, in forum: ASP .Net Web Controls
    Replies:
    2
    Views:
    202
    Teemu Keiski
    Feb 14, 2004
Loading...

Share This Page