【问题标题】:Asynchronously load images with jQuery使用 jQuery 异步加载图像
【发布时间】:2011-05-16 03:55:22
【问题描述】:

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

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

   },
   error: function(r,x) {

   }
});

但它总是返回错误,甚至可以像这样加载图像吗?

我尝试使用.load 方法并且它有效,但我不知道如果图像不可用(404)如何设置超时。我该怎么做?

【问题讨论】:

标签: javascript jquery ajax image jquery-load


【解决方案1】:

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

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

【讨论】:

  • 超时和404怎么办?
  • 如何设置超时?我尝试了这种方法,但不知何故页面仍在等待图像加载。
  • 如果你检查浏览器的时间线,例如谷歌浏览器的开发工具时间线,你会看到创建任何 DOM 元素(无论你是否将它附加到 DOM 显然是无关紧要的)然后设置它的source 将它添加到当前文档的加载列表中 - 因此页面将不会完成“加载”,直到加载创建的元素。您的解决方案实际上不是异步事件,因为 window.load() 在图像加载之前不会触发,可能会延迟某些 paintlayout 操作,并且肯定会延迟任何 onload 事件依赖项。跨度>
  • @TomAuger :那么我们怎样才能让它真正异步呢?我刚刚用 load() 测试了代码,它不是异步的。
  • @gidzior 它在 IE8 中不起作用,因为您无法使用 jquery 在 IE8 中设置 SRC 属性。参考这里:stackoverflow.com/questions/12107487/…
【解决方案2】:

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

我遇到过 onload 处理程序不是正确选择的用例。就我而言,当通过 javascript 打印时。所以实际上有两个选项可以使用 AJAX 样式:

解决方案 1

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

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

因此,您可以使用 Ajax 加载图像 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();
});   

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

干杯, 会

【讨论】:

  • 如果您可以接受当前的浏览器支持状态 (caniuse.com/#search=Blob),您可以使用 Blobs 代替数据 URI。与使用 base64 编码的数据 URI 相比,这种“感觉”没有那么麻烦,而且内存浪费也更少(因为 base64 不是一种内存效率高的格式),尽管后者在现实世界中的大部分时间可能并不重要。
【解决方案3】:

使用 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 代码可以缩写,但这样可以理解。

【讨论】:

  • 提示:如果你使用data-标签,通过$(element).data('src')而不是$(element).attr('data-src')访问它们会更容易
  • 其实今天我不会再使用jQuery了。但这是个人品味的问题,取决于您正在构建的网站的规模。但当时的热门话题是“进步图像”,也许这是值得关注的。 smashingmagazine.com/2018/02/…
【解决方案4】:
$(<img />).attr('src','http://somedomain.com/image.jpg');

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

【讨论】:

    【解决方案5】:

    您可以使用延迟对象进行异步加载。

    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 之前,以防止缓存出现问题。

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        这也有效..

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

        【讨论】:

          【解决方案8】:

          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>
          

          【讨论】:

          • 抱歉,我稍微误解了你的 Q,我以为你正在加载正在变化的图像或其他东西(因此是 ajax 位)
          【解决方案9】:

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

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

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

          【讨论】:

            【解决方案10】:

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

            【讨论】:

              【解决方案11】:
              $(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">');
                      }
                  });
              

              【讨论】:

              • 它工作得很好,在加载主页时我们可以设置不同的图像——来自北极星
              • 杂乱无章,与回答问题无关。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-04-08
              • 1970-01-01
              • 1970-01-01
              • 2011-11-27
              相关资源
              最近更新 更多