Asynchronously load images with jQuery
Asked Answered
A

12

147

I want to load external images on my page asynchronously using jQuery and I have tried the following:

$.ajax({ 
   url: "http://somedomain.com/image.jpg", 
   timeout:5000,
   success: function() {

   },
   error: function(r,x) {

   }
});

But it always returns error, is it even possible to load image like this?

I tried to use .load method and it works but I have no idea how I can set timeout if the image is not available (404). How can I do this?

Acuff answered 26/11, 2010 at 11:51 Comment(1)
This works for me: #6150789Salaried
D
205

No need for ajax. You can create a new image element, set its source attribute and place it somewhere in the document once it has finished loading:

var img = $("<img />").attr('src', 'http://somedomain.com/image.jpg')
    .on('load', function() {
        if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
            alert('broken image!');
        } else {
            $("#something").append(img);
        }
    });
Di answered 26/11, 2010 at 11:54 Comment(15)
what to do with the timeout and 404?Acuff
@Acuff - Please see my edit. You can test the image's complete property, and natural width.Di
how to set timeout with this? I tried this method but somehow the page still waits for the image to load.Acuff
If you check your browser's timeline, for example, Google Chrome's dev tools timeline, you will see that creating any DOM element (whether or not you attach it to the DOM is irrelevant apparently) and then setting its source adds it to the current document's load list - so the page will NOT finish "loading" until that created element is loaded. Your solution is actually not an asyncrhonous event in the sense that window.load() will not fire until the image has loaded, possibly deferring certain paint or layout operations, and certainly delaying any onload event dependencies.Infelicitous
@TomAuger : So how can we make it really asynchronous? I just tested the code with load() and it is NOT asynchronous.Reduplicate
If you load it on some different event then it is Asynchronous, surely. I've used similar code on my site for a portfolio, when a user clicks on a project, the images are loaded into the appropriate divs etc (= async).Furnivall
it doesn't work in IE8, anybody knows why ?? i have "broken image" alertCardigan
DONT USER Load, you cant cancel it after it is calledFanaticism
@karim, The advantage of Ajax is that we can abort the request it anytime we want.Garner
Your solution works perfectly, but why does it? I didn't find any documentation that said you can call load without any URLHerald
@Cardigan It doesn't work in IE8 because you can't set the SRC attribute in IE8 using jquery. refer here: #12107987Lumber
didn't he want it through ajax though? i want to track progress, and it can't be done this wayKinship
I think what most people want to know, is how do you do this in jQuery or plain JS to understand the underlying differences on how different data is processed. My curiosity originated from AJAX = Asynchronous JavaScript and XML. So what if I am interested in a non XML asynch request? What if I want an image? And so on...Singularize
@Acuff it's been a while since you asked the question, but did you manage to solve the timeout problem? I'm having the exact same problem.Stripper
@Herald here's the documentation on calling .load() without passing a URL as the first argument: api.jquery.com/load-event. The docs note that "The Ajax module also has a method named .load(). Which one is fired depends on the set of arguments passed." Note also that (presumably because the existence of two distinct functions called .load() confused people - like you!) using .load() just to bind a handler is deprecated in favour of .on('load', handler). I'm editing the answer to use the non-deprecated form.Moussaka
S
81

IF YOU REALLY NEED TO USE AJAX...

I came accross usecases where the onload handlers were not the right choice. In my case when printing via javascript. So there are actually two options to use AJAX style for this:

Solution 1

Use Base64 image data and a REST image service. If you have your own webservice, you can add a JSP/PHP REST script that offers images in Base64 encoding. Now how is that useful? I came across a cool new syntax for image encoding:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhE..."/>

So you can load the Image Base64 data using Ajax and then on completion you build the Base64 data string to the image! Great fun :). I recommend to use this site http://www.freeformatter.com/base64-encoder.html for image encoding.

$.ajax({ 
    url : 'BASE64_IMAGE_REST_URL', 
    processData : false,
}).always(function(b64data){
    $("#IMAGE_ID").attr("src", "data:image/png;base64,"+b64data);
});

Solution2:

Trick the browser to use its cache. This gives you a nice fadeIn() when the resource is in the browsers cache:

var url = 'IMAGE_URL';
$.ajax({ 
    url : url, 
    cache: true,
    processData : false,
}).always(function(){
    $("#IMAGE_ID").attr("src", url).fadeIn();
});   

However, both methods have its drawbacks: The first one only works on modern browsers. The second one has performance glitches and relies on assumption how the cache will be used.

cheers, will

Synecology answered 3/10, 2012 at 18:11 Comment(1)
If the current state of browser support is acceptable to you (caniuse.com/#search=Blob), you can use Blobs instead of data URIs. This 'feels' less hacky than using base64-encoded data URIs and is also less wasteful of memory (since base64 is not a memory-efficient format), although the latter probably doesn't matter most of the time in the real world.Moussaka
G
13

Using jQuery you may simply change the "src" attribute to "data-src". The image won't be loaded. But the location is stored with the tag. Which I like.

<img class="loadlater" data-src="path/to/image.ext"/>

A Simple piece of jQuery copies data-src to src, which will start loading the image when you need it. In my case when the page has finished loading.

$(document).ready(function(){
    $(".loadlater").each(function(index, element){
        $(element).attr("src", $(element).attr("data-src"));
    });
});

I bet the jQuery code could be abbreviated, but it is understandable this way.

Goulden answered 14/6, 2015 at 17:39 Comment(2)
Tip: if you're using the data- tags, it's a fair bit easier to access them via $(element).data('src') instead of $(element).attr('data-src')Canonicate
Actually today I would not use jQuery anymore. But thats a question of personal taste, and depends on the scale of the website you are building. But the hot topic of the time is "Progressive Images", maybe that is something to look in to. smashingmagazine.com/2018/02/…Goulden
L
9
$(<img />).attr('src','http://somedomain.com/image.jpg');

Should be better than ajax because if its a gallery and you are looping through a list of pics, if the image is already in cache, it wont send another request to server. It will request in the case of jQuery/ajax and return a HTTP 304 (Not modified) and then use original image from cache if its already there. The above method reduces an empty request to server after the first loop of images in the gallery.

Lakia answered 15/7, 2011 at 13:39 Comment(0)
R
5

You can use a Deferred objects for ASYNC loading.

function load_img_async(source) {
    return $.Deferred (function (task) {
        var image = new Image();
        image.onload = function () {task.resolve(image);}
        image.onerror = function () {task.reject();}
        image.src=source;
    }).promise();
}

$.when(load_img_async(IMAGE_URL)).done(function (image) {
    $(#id).empty().append(image);
});

Please pay attention: image.onload must be before image.src to prevent problems with cache.

Repeated answered 20/10, 2014 at 20:31 Comment(0)
H
3

If you just want to set the source of the image you can use this.

$("img").attr('src','http://somedomain.com/image.jpg');
Housebound answered 26/11, 2010 at 11:54 Comment(0)
F
3

This works too ..

var image = new Image();
image.src = 'image url';
image.onload = function(e){
  // functionalities on load
}
$("#img-container").append(image);
Foramen answered 2/11, 2016 at 13:49 Comment(0)
M
2

AFAIK you would have to do a .load() function here as apposed to the .ajax(), but you could use jQuery setTimeout to keep it live (ish)

<script>
 $(document).ready(function() {
 $.ajaxSetup({
    cache: false
});
 $("#placeholder").load("PATH TO IMAGE");
   var refreshId = setInterval(function() {
      $("#placeholder").load("PATH TO IMAGE");
   }, 500);
});
</script>
Misfortune answered 26/11, 2010 at 11:53 Comment(1)
sorry i slightly misunderstood your Q, i thought you were loading images that were changing or something (hence the ajax bit)Misfortune
L
2

use .load to load your image. to test if you get an error ( let's say 404 ) you can do the following:

$("#img_id").error(function(){
  //$(this).hide();
  //alert("img not loaded");
  //some action you whant here
});

careful - .error() event will not trigger when the src attribute is empty for an image.

Lovelorn answered 26/11, 2010 at 12:0 Comment(0)
T
0
$(function () {
       
        if ($('#hdnFromGLMS')[0].value == 'MB9262') {
            $('.clr').append('<img src="~/Images/CDAB_london.jpg">');
        }
        else
        {
            $('.clr').css("display", "none");
            $('#imgIreland').css("display", "block");
            $('.clrIrland').append('<img src="~/Images/Ireland-v1.jpg">');
        }
    });
Trehalose answered 20/2, 2016 at 6:39 Comment(2)
Its working perfectely, while loading home page we can set different images -- from PolarisTrehalose
Too much clutter, unrelated to answering the question.Canonicate
C
0

//Puedes optar por esta solución:

var img = document.createElement('img');
img.setAttribute('src', element.source)
img.addEventListener('load', function(){
if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
                            alert('broken image!');
                        } else {
                        $("#imagenesHub").append(img);
                        }
                    });
Concatenation answered 12/7, 2021 at 2:19 Comment(0)
G
0

It is 2023 and neither jQuery, nor JavaScript are needed to asynchronously load images:

The loading="lazy" attribute will take care of it.

<img src="image.jpg" alt="..." loading="lazy" />

The browser will start loading the image when the user scrolls close to its position in the DOM.

You can take a look at this article from MDN on lazy loading: https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading

Goulden answered 27/2, 2023 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.