24

On my album slide show page, i have code like

<span style="display:none;">
   <img id="id1" src="~$imageUrl`" onload="javascript:showImage();">
</span>

<span>
    // show loader.
</span>

in showImage(), i am sure the image is loaded, so i show the image and hide the loader.

Now when user clicks on next, i need to change the src of the image. Now i need don't know how to set src only when image is loaded.

Raptor
  • 53,206
  • 45
  • 230
  • 366
Deepak Malhotra
  • 243
  • 1
  • 2
  • 6

11 Answers11

45

you can just append another hidden img element and swap them in onload event.

Or use single image element and use javascript like:

var _img = document.getElementById('id1');
var newImg = new Image;
newImg.onload = function() {
    _img.src = this.src;
}
newImg.src = 'http://whatever';

this code should preload the image and show it when it's ready

Adassko
  • 5,201
  • 20
  • 37
  • 3
    You should first set `onload` and then `src`, since theoretically the image could load before the `onload` function is set, and thus seemingly fail to load. – Yeti Apr 07 '14 at 13:00
  • 2
    @Yeti: actually no - that's impossible. The browser will start downloading when script stops his execution. You can check this in various different ways – Adassko May 04 '14 at 19:05
  • 1
    @Adassko, take a look at this question: http://stackoverflow.com/questions/4776670/should-setting-an-image-src-to-data-url-be-available-immediately I've encountered this problem myself as well in some very specific cases for specific browser versions (I can't reproduce it on Firefox at the moment). Plus, there is no harm in setting `onload` before `src`. – Yeti May 06 '14 at 11:24
  • @Yeti: I've never seen this kind of behaviour, but I agree - no harm in doing this that way. Edited – Adassko May 06 '14 at 12:19
  • @Yeti, JavaScript user code is single threaded, but with event loop and internal exception in ajax requests. How behaviour, which is described by you is possible? http://stackoverflow.com/questions/4776670/should-setting-an-image-src-to-data-url-be-available-immediately writes about immediate accesablity of image attributes (which in not really correct programming way) without waiting of onload event. Also it writes, that IE9b does not call onload after img.src is setting, so it is problem of IE9b and just not generating of event, when it MUST be generated. – user1742529 Feb 13 '17 at 12:29
  • @user1742529 Perhaps not, but that is not really the point. Setting `onload` before `src` is semantically correct. – Yeti Feb 13 '17 at 15:03
6

Use a new image object each time you want to load a picture :

var image = new Image();
image.onload = function () {
    document.getElementById('id1').setAttribute('src', this.src);
};
image.src = 'http://path/to/image';
6

Sorry guys.

You can't rely on the image load event to fire but you can kind of rely on it in some situations and fallback to a maximum load time allowed. In this case, 10 seconds. I wrote this and it lives on production code for when people want to link images on a form post.

function loadImg(options, callback) {
  var seconds = 0,
  maxSeconds = 10,
  complete = false,
  done = false;

  if (options.maxSeconds) {
    maxSeconds = options.maxSeconds;
  }

  function tryImage() {
    if (done) { return; }
    if (seconds >= maxSeconds) {
      callback({ err: 'timeout' });
      done = true;
      return;
    }
    if (complete && img.complete) {
      if (img.width && img.height) {
        callback({ img: img });
        done = true;
        return;
      }
      callback({ err: '404' });
      done = true;
      return;
    } else if (img.complete) {
      complete = true;
    }
    seconds++;
    callback.tryImage = setTimeout(tryImage, 1000);
  }
  var img = new Image();
  img.onload = tryImage();
  img.src = options.src;
  tryImage();
}

use like so:

loadImage({ src : 'http://somewebsite.com/image.png', maxSeconds : 10 }, function(status) {
  if(status.err) {
    // handle error
    return;
  }
  // you got the img within status.img
}); 

Try it on JSFiddle.net

http://jsfiddle.net/2Cgyg/6/

King Friday
  • 25,132
  • 12
  • 90
  • 84
  • "You can't rely on the image load event to fire" Why?? – Brad Apr 30 '19 at 17:51
  • There was some inconstancies with caching in chrome at the time of this when the load event would not fire on 304 – King Friday Apr 30 '19 at 21:04
  • Why not simply using jQuery? It makes things so much more simple: https://stackoverflow.com/a/63003728/1243247 – João Pimentel Ferreira Jul 20 '20 at 21:01
  • This is also polluting the global scope with an "img" variable, maybe you should refactor using const and a local variable? Also, why can't we use the onload event? – santamanno Jul 27 '21 at 15:21
  • @santamanno thx for question...at the time of writing the behavior of caching in chrome would not callback onload. Also "img" is called within a function which is scoped to that function. If it were arrow syntax you would be correct but assuming it was defined at root scope. – King Friday Jul 27 '21 at 17:19
  • @King Friday Apologies, you’re correct about the scope. Concerning then cache, I’d still prefer other cache busting mechanisms then a convoluted code solution, but I guess it boils down to a matter of taste. Luckily nowadays Image.onload seems to work fine. – santamanno Jul 28 '21 at 19:39
  • 1
    @santamanno thx, i'll try to get some time to investigate this behavior and will remove if I cannot reproduce as it may be incorrect at this time. Better to handle at network level as you suggest. – King Friday Jul 28 '21 at 23:38
3
<span>
    <img id="my_image" src="#" />
</span>

<span class="spanloader">

    <span>set Loading Image Image</span>


</span>

<input type="button" id="btnnext" value="Next" />


<script type="text/javascript">

    $('#btnnext').click(function () {
        $(".spanloader").hide();
        $("#my_image").attr("src", "1.jpg");
    });

</script>
2

If you are loading the image via AJAX you could use a callback to check if the image is loaded and do the hiding and src attribute assigning. Something like this:

$.ajax({ 
  url: [image source],
  success: function() {
  // Do the hiding here and the attribute setting
  }
});

For more reading refer to this JQuery AJAX

bruhbruh
  • 313
  • 1
  • 14
0

Try this.You have some symbols in $imageUrl

<img id="id1" src="$imageUrl" onload="javascript:showImage();">
웃웃웃웃웃
  • 11,829
  • 15
  • 59
  • 91
0

You can try this:

<img id="id1" src="url/to/file.png" onload="showImage()">

function showImage() {
 $('#id1').attr('src', 'new/file/link.png');
}

Also, try to remove the ~, that is just the operator, that is needed for Server-Side (for example ASP.NET) you don't need it in JS.

This way, you can change the attribute for the image.

Here is the fiddle: http://jsfiddle.net/afzaal_ahmad_zeeshan/8H4MC/

Afzaal Ahmad Zeeshan
  • 15,669
  • 12
  • 55
  • 103
0

See this tutorial: Loading images with native JavaScript and handling of events for showing loading spinners

It tells you how to load images with native JavaScript and how to handle events for showing loading spinners. Basically, you create a new Image(); and handle the event correctly then. That should work in all browsers, even in IE7 (maybe even below IE7, but I did not test that...)

Nabi
  • 2,536
  • 1
  • 16
  • 18
0

this worked for me though... i wanted to display the image after the pencil icon is being clicked... and i wanted it seamless.. and this was my approach..

pencil button to display image

i created an input[file] element and made it hidden,

<input type="file" id="upl" style="display:none"/>

this input-file's click event will be trigged by the getImage function.

<a href="javascript:;" onclick="getImage()"/>
    <img src="/assets/pen.png"/>
</a>

<script>
     function getImage(){
       $('#upl').click();
     }
</script>

this is done while listening to the change event of the input-file element with ID of #upl.

   $(document).ready(function(){
     
       $('#upl').bind('change', function(evt){
         
    var preview = $('#logodiv').find('img');
    var file    = evt.target.files[0];
    var reader  = new FileReader();
  
    reader.onloadend = function () {
   $('#logodiv > img')
    .prop('src',reader.result)  //set the scr prop.
    .prop('width', 216);  //set the width of the image
    .prop('height',200);  //set the height of the image
    }
  
    if (file) {
   reader.readAsDataURL(file);
    } else {
   preview.src = "";
    }
  
    });

   })

and BOOM!!! - it WORKS....

Ande Caleb
  • 1,163
  • 1
  • 14
  • 35
0

Simplest load image from JS to DOM-element:

element.innerHTML += "<img src='image.jpg'></img>";

With onload event:

element.innerHTML += "<img src='image.jpg' onload='javascript:showImage();'></img>";
0

just click on image and will change:

<div>
 <img src="https://i.imgur.com/jgyJ7Oj.png" id="imgLoad">
</div>

<script type='text/javascript'>
 var img = document.getElementById('imgLoad'); 
 img.onclick = function() { img.src = "https://i.imgur.com/PqpOLwp.png"; }
 </script>
Mazen Alhrazi
  • 336
  • 1
  • 3
  • 10