如何取消jquery.load()?

时间:2010-05-11 17:58:25

标签: jquery image timeout jquery-load

当load()在5秒内没有返回时,我想取消.load()操作。如果是这样,我会显示错误消息,例如'抱歉,没有图片加载'。

我拥有的是......

......超时处理:

jQuery.fn.idle = function(time, postFunction){  
    var i = $(this);  
    i.queue(function(){  
        setTimeout(function(){  
            i.dequeue();
            postFunction();  
        }, time);  
    });
    return $(this); 
};

...初始化错误消息超时:

var hasImage = false;

$('#errorMessage')
    .idle(5000, function() {

        if(!hasImage) {
            // 1. cancel .load()            
            // 2. show error message
        }
    });

......图片加载:

$('#myImage')
     .attr('src', '/url/anypath/image.png')
     .load(function(){
         hasImage = true;
         // do something...
      });

我唯一想知道的是如何取消正在运行的负载()(如果可能的话)。

修改:

另一种方法:如何阻止.load()方法在返回时调用它的回调函数?

7 个答案:

答案 0 :(得分:11)

如果你想要任何自定义处理,你就是不能使用jQuery.load()函数。你必须升级到jQuery.ajax(),我建议你使用它,因为你可以用它做更多的事情,特别是如果你需要任何类型的错误处理,它将是必要的。

使用jQuery.ajax的beforeSend选项并捕获xhr。然后你可以创建回调,它可以在超时后取消xhr,并根据需要取消回调。

此代码未经过测试,但应该让您入门。

var enableCallbacks = true;
var timeout = null;
jQuery.ajax({
  ....
  beforeSend: function(xhr) {
    timeout = setTimeout(function() {
      xhr.abort();
      enableCallbacks = false;
      // Handle the timeout
      ...
    }, 5000);
  },
  error: function(xhr, textStatus, errorThrown) {
    clearTimeout(timeout);
    if (!enableCallbacks) return;
    // Handle other (non-timeout) errors
  },
  success: function(data, textStatus) {
    clearTimeout(timeout);
    if (!enableCallbacks) return;
    // Handle the result
    ...
  }
});

答案 1 :(得分:3)

你改写的第二个问题:
如何取消使用.load()方法创建的待处理回调函数?

您可以使用此核心'取消所有jquery回调。选项:

$('#myImage').unbind('load');

答案 2 :(得分:2)

我认为最简单的方法是直接使用$.ajax。这样你可以开始超时,并从超时设置一个标志,ajax调用上的处理程序可以检查。超时也可以显示消息或其他任何内容。

答案 3 :(得分:2)

如果在加载JQuery后加载此代码,则可以使用timeout参数调用.load()。

jQuery.fn.load = function( url, params, callback, timeout ) {
    if ( typeof url !== "string" ) {
        return _load.call( this, url );

    // Don't do a request if no elements are being requested
    } else if ( !this.length ) {
        return this;
    }

    var off = url.indexOf(" ");
    if ( off >= 0 ) {
        var selector = url.slice(off, url.length);
        url = url.slice(0, off);
    }

    // Default to a GET request
    var type = "GET";

    // If the second parameter was provided
    if ( params ) {
        // If it's a function
        if ( jQuery.isFunction( params ) ) {
            if( callback && typeof callback === "number"){
                timeout = callback;
                callback = params;
                params = null;
            }else{
                // We assume that it's the callback
                callback = params;
                params = null;
                timeout = 0;
            }
        // Otherwise, build a param string
        } else if( typeof params === "number"){
            timeout = params;
            callback = null;
            params = null;
        }else if ( typeof params === "object" ) {
            params = jQuery.param( params, jQuery.ajaxSettings.traditional );
            type = "POST";
            if( callback && typeof callback === "number"){
                timeout = callback;
                callback = null;
            }else if(! timeout){
                timeout = 0;
            }
        }
    }

    var self = this;

    // Request the remote document
    jQuery.ajax({
        url: url,
        type: type,
        dataType: "html",
        data: params,
        timeout: timeout,
        complete: function( res, status ) {
            // If successful, inject the HTML into all the matched elements
            if ( status === "success" || status === "notmodified" ) {
                // See if a selector was specified
                self.html( selector ?
                    // Create a dummy div to hold the results
                    jQuery("<div />")
                        // inject the contents of the document in, removing the scripts
                        // to avoid any 'Permission Denied' errors in IE
                        .append(res.responseText.replace(rscript, ""))

                        // Locate the specified elements
                        .find(selector) :

                    // If not, just inject the full result
                    res.responseText );
            }

            if ( callback ) {
                self.each( callback, [res.responseText, status, res] );
            }
        }
    });

    return this;
};

不确定您是否有兴趣覆盖任何“标准”JQuery函数,但这将允许您按照您描述的方式使用.load()。

答案 4 :(得分:1)

我认为你不能从这里到达 - 正如@Pointy所提到的,你需要访问XmlHttpRequest对象,这样你才能访问它上面的.abort()方法。为此,您需要.ajax() jQuery API将对象返回给您。

除了能够中止请求之外,另一种需要考虑的方法是将超时的知识添加到回调函数中。你可以这两种方式 - 第一种:

var hasImage = false;

$('#errorMessage')
    .idle(5000, function() {

        if(!hasImage) {
            // 1. cancel .load()            
            // 2. show error message
            // 3. Add an aborted flag onto the element(s)
            $('#myImage').data("aborted", true);
        }
    });

你的回调:

$('#myImage')
     .attr('src', '/url/anypath/image.png')
     .load(function(){
         if($(this).data("aborted")){
             $(this).removeData("aborted");
             return;
         }
         hasImage = true;
         // do something...
      });

或者您可以绕过此特定功能的空闲状态:

$('#myImage')
     .attr('src', '/url/anypath/image.png')
     .data("start", (new Date()).getTime())
     .load(function(){
         var start = $(this).data("start");
         $(this).removeData("start");
         if(((new Date()).getTime() - start) > 5000)
             return;

         hasImage = true;
         // do something...
      });

这两种方法都不理想,但我不认为你可以直接取消jQuery 1.4的加载 - 但是对jQuery团队来说可能是一个不错的功能请求。

答案 5 :(得分:0)

$('#myImage').load(function(){...})不是加载图像的函数调用,实际上是将回调绑定到onload event的简写。

因此,如其他答案所示,在.load() method中添加timeout参数将无效。

它认为你的两个选择是:

  1. 继续前进 跟随并做类似的事情 $('#myImage').attr('src', '');来 在时间之后取消图像加载 out,或

  2. 找到一些方法来使用$.ajax( { ... , timeout: 5000, ...} );加载 图像而不是让图像 浏览器通过自动执行 <img src="...">属性。

答案 6 :(得分:0)

您可以在加载图像之前设置超时,并测试加载错误。

function LoadImage(yourImage) {

    var imageTimer = setTimeout(function () {
        //image could not be loaded:
        alert('image load timed out');
    }, 10000); //10 seconds

    $(yourImage).load(function (response, status, xhr) {
        if (imageTimer) {

            if (status == 'error') {
                //image could not be loaded:
                alert('failed to load image');

            } else {
                //image was loaded:
                clearTimeout(imageTimer);
                //display your image...
            }

        }
    });

}