用jQuery异步加载图像


142

我想使用jQuery在页面上异步加载外部图像,并且尝试了以下方法:

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

   },
   error: function(r,x) {

   }
});

但是它总是返回错误,是否有可能像这样加载图像?

我尝试使用.loadmethod,但是它可以工作,但是我不知道如果图像不可用,如何设置超时时间(404)。我怎样才能做到这一点?


Answers:


199

无需ajax。您可以创建一个新的图像元素,设置其source属性,并在完成加载后将其放置在文档中的某个位置:

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

20
超时和404怎么办?
Arief

1
如何设置超时?我尝试了这种方法,但是页面仍然以某种方式等待图像加载。
Arief 2010年

7
如果您查看浏览器的时间轴(例如Google Chrome的开发工具时间轴),将会看到创建任何DOM元素(无论是否将其附加到DOM都是无关紧要的),然后设置其来源会将其添加到当前文档的负载中列表-这样页面将无法完成“加载”,直到该创建的元素被加载。您的解决方案实际上不是异步事件,因为window.load()在图像加载之前不会触发,这可能会延迟某些操作paint或某些layout操作,并且肯定会延迟任何onload事件依赖项。
汤姆·奥格

2
@TomAuger:那么我们如何使其真正异步?我只是用load()测试了代码,它不是异步的。
basZero

2
@gidzior在IE8中不起作用,因为您无法使用jquery在IE8中设置SRC属性。请参阅此处:stackoverflow.com/questions/12107487/…– 2013
丰富

78

如果您真的需要使用AJAX ...

我遇到了一些用例,其中onload处理程序不是正确的选择。以我为例,通过javascript打印时。因此,实际上有两种方法可以使用AJAX样式:

解决方案1

使用Base64图像数据和REST图像服务。如果您拥有自己的Web服务,则可以添加JSP / PHP REST脚本,该脚本以Base64编码提供图像。现在有什么用?我遇到了一个很酷的图像编码新语法:

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

因此,您可以使用Ajax加载Image Base64数据,然后在完成后将Base64数据字符串构建到图像!非常有趣 :)。我建议使用此网站http://www.freeformatter.com/base64-encoder.html进行图像编码。

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

解决方案2:

欺骗浏览器以使用其缓存。当资源位于浏览器缓存中时,这为您提供了一个不错的fadeIn():

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

但是,这两种方法都有其缺点:第一种方法仅适用于现代浏览器。第二个有性能故障,并依赖于将如何使用缓存的假设。

欢呼,将


1
如果您接受浏览器支持的当前状态(caniuse.com/#search=Blob),则可以使用Blob代替数据URI。与使用base64编码的数据URI相比,此方法“感觉”不到hacky,并且对内存的浪费也较少(因为base64不是内存有效的格式),尽管后者在现实世界中大部分时间都无关紧要。
马克·阿默里

11

使用jQuery,您可以简单地将“ src”属性更改为“ data-src”。图片不会被加载。但是位置标签一起存储。我喜欢

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

一个简单的jQuery片段将data-src复制到src,它将在需要时开始加载图像。就我而言,页面已完成加载。

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

我敢打赌,jQuery代码可以缩写,但这是可以理解的。


4
提示:如果您使用的是data-标签,则可以通过$(element).data('src')而不是$(element).attr('data-src')
Maxim Kumpan的方式

实际上,今天我不再使用jQuery。但这就是个人品味的问题,并且取决于您所建网站的规模。但是当时最热门的话题是“渐进式图像”,也许这是值得研究的。smashingmagazine.com/2018/02/...
htho

8
$(<img />).attr('src','http://somedomain.com/image.jpg');

应该比ajax更好,因为如果它是一个图库并且您正在循环浏览图片列表,并且该图像已经在缓存中,则它不会向服务器发送另一个请求。如果是jQuery / ajax,它将请求并返回HTTP 304(未修改),然后使用缓存中的原始图像(如果已存在)。上述方法减少了画廊中图像的第一个循环之后对服务器的空请求。


4

您可以使用Deferred对象进行ASYNC加载。

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

请注意:image.onload必须在image.src之前,以防止缓存问题。


3

如果您只想设置图像的来源,则可以使用它。

$("img").attr('src','http://somedomain.com/image.jpg');

3

这也可以..

var image = new Image();
image.src = 'image url';
image.onload = function(e){
  // functionalities on load
}
$("#img-container").append(image);

2

AFAIK,您必须在此像.ajax()一样执行.load()函数,但是您可以使用jQuery setTimeout使其保持活动状态(ish)

<script>
 $(document).ready(function() {
 $.ajaxSetup({
    cache: false
});
 $("#placeholder").load("PATH TO IMAGE");
   var refreshId = setInterval(function() {
      $("#placeholder").load("PATH TO IMAGE");
   }, 500);
});
</script>

2
抱歉,我稍微误会了您的Q,我以为您正在加载正在更改的图像或其他内容(因此使用了ajax位)
benhowdle89 2010年

2

使用.load加载图像。要测试是否收到错误(例如404),可以执行以下操作:

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

注意-当图像的src属性为空时,不会触发.error()事件。


0

$(函数(){

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

它工作得非常完美,在加载首页时,我们可以设置不同的图像-来自Polaris
MadhaviLatha Bathini

过于混乱,与回答问题无关。
Maxim Kumpan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.