Как отменить jquery.load ()?

Я хотел бы отменить .load () операция, когда загрузка () не возвращается через 5 секунд. Если это так, я показываю сообщение об ошибке как 'жаль, никакое загруженное изображение'.

То, что я имею...

... обработка тайм-аута:

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 () метод для вызова, это - функция обратного вызова, когда он возвращается?

18
задан Dirk 10 April 2014 в 00:43
поделиться

4 ответа

Если вам нужна какая-либо пользовательская обработка, подобная этой, вы просто не можете использовать функцию jQuery.load(). Вам придется перейти на jQuery.ajax(), которую я рекомендую в любом случае, поскольку с ней вы можете сделать гораздо больше, особенно если вам нужна какая-либо обработка ошибок, это будет необходимо.

Используйте опцию beforeSend для jQuery.ajax и перехватывайте 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
    ...
  }
});
11
ответ дан 30 November 2019 в 09:03
поделиться

Я думаю, что проще всего было бы напрямую использовать $. Ajax . Таким образом, вы можете запустить тайм-аут, а из тайм-аута установить флаг, который может проверить обработчик вызова ajax. По таймауту также может отображаться сообщение или что-то еще.

2
ответ дан 30 November 2019 в 09:03
поделиться

Я не думаю, что вы можете добраться отсюда - как упоминал @Pointy, вам нужно добраться до объекта XmlHttpRequest, чтобы вы могли получить доступ к .abort () на нем. Для этого вам понадобится jQuery API .ajax () , который возвращает вам объект.

За исключением возможности прервать запрос, следует рассмотреть еще один способ - добавить информацию о тайм-ауте в функцию обратного вызова. Вы можете сделать это двумя способами - первый:

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.

1
ответ дан 30 November 2019 в 09:03
поделиться

Если вы загрузите этот код после загрузки JQuery, вы сможете вызвать .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 () так, как вы описали.

2
ответ дан 30 November 2019 в 09:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: