Как прервать загрузку изображений <img>без использования window.stop () - PullRequest
43 голосов
/ 03 августа 2011

У меня очень длинная страница, которая динамически загружает изображения при прокрутке пользователей.

Однако, если пользователь быстро прокручивает определенную часть страницы, я не хочу, чтобы изображения продолжали загружаться в эту часть страницы, которая теперь не отображается.

На странице одновременно происходит множество других запросов, кроме загрузки изображений, поэтому тупое срабатывание window.stop () для события прокрутки недопустимо.

Я попытался удалить и очистить атрибуты img src для изображений, которые больше не отображаются, однако, поскольку запрос уже запущен, изображение продолжает загружаться.

Помните, что изображение src было заполнено, когда пользователь кратко пролистал эту часть страницы. Однажды, однако, я не мог получить это изображение от остановки загрузки без использования window.stop (). Очистка src не сработала. (Chrome & FF)

Подобные посты, которые я нашел, приближаются, но, похоже, не решают эту проблему:

Ответы [ 7 ]

16 голосов
/ 07 августа 2011

То, что вы пытаетесь сделать, - это неправильный подход, как упомянуто nrabinowitz .Вы не можете просто «отменить» процесс загрузки изображения (установка атрибута src на пустую строку - не очень хорошая идея ).На самом деле, даже если бы вы могли, это только ухудшило бы ситуацию, поскольку ваш сервер постоянно отправлял данные, которые были бы отменены, увеличивая коэффициент загрузки и замедляя его.Также учтите следующее:

  1. , если ваш пользователь неистово прокручивает страницу вверх и вниз, он / она будет ожидать некоторых задержек загрузки.
  2. с задержкой по таймауту (например, 200 мс)перед тем, как начать загрузку части страницы, это вполне приемлемо, и сколько раз вы остановитесь и прыгнете через 200 мс на вашей странице?Даже если это произойдет, это возвращается к пункту 1
  3. Насколько велики ваши изображения?Даже медленный сервер может обслуживать несколько десятков 3Kb thunbnails в секунду.Если на вашем сайте есть изображения большего размера, рассмотрите возможность использования изображений низкого и высокого разрешения с некоторыми компонентами, такими как lightBox

Часто проблемы с компьютером - это просто проблемы проектирования.

** РЕДАКТИРОВАТЬ **

Вот идея:

  1. ваша страница должна отображать DIV контейнеров с шириной и высотой ожидаемого размера изображения(используйте CSS для стиля).Внутри каждого DIV добавьте ссылку.Например:

    <div class="img-wrapper thumbnail">
       <a href="http://www.domain.com/path/to/image">Loading...</a>
    </div>
    
  2. Добавьте этот Javascript (непроверенный, идея описывает себя)

    $(function() {
    
    var imgStack;
    var loadTimeout;
    
    $(window).scroll(function() {
       imgStack = null;
       if (loadTimeout) clearTimeout(loadTimeout);
    
       loadTimeout = setTimeout(function() {
    
          // get all links visible in the view port
          // should be an array or jQuery object
          imgStack = ...
    
          loadNextImage();
       }, 200);                // 200 ms delay
    });
    
    function loadNextImage() {
       if (imgStack && imgStack.length) {
          var nextLink = $(imgStack.pop());   // get next image element
    
          $('<img />').attr('src', nextLink.attr('href'))
            .appendTo(nextLink.parent())
            .load(function() {
               loadNextImage();
            });
    
          // remove link from container (so we don't precess it twice)
          nextLink.remove();
       }
    };
    
    });
    
12 голосов
/ 10 августа 2011

Ну, моя идея:

1) инициирует AJAX-запрос для изображения, если оно успешно выполняется, изображение отправляется в кэш браузера, и после того, как вы установите атрибут 'src', изображение показывается из кэша

2) вы можете прервать XHR

Я написал крошечный сервер с экспресс-эмуляцией загрузки огромного изображения (на самом деле он просто ждет 20 секунд, а затем возвращает изображение). Тогда у меня есть это в моем HTML:

<!DOCTYPE html>
<html>
    <head>
        <style>
            img {
                width: 469px;
                height: 428px;
                background-color: #CCC;
                border: 1px solid #999;
            }
        </style>
    </head>

    <body>
        <img data-src="./img" src="" />
        <br />
        <a id="cancel" href="javascript:void(0)">CANCEL</a>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(function () {
                var xhr, img = $('img'), src = img.data('src');

                xhr = $.ajax(src, {
                    success: function (data) { img.attr('src', src) }
                });

                $('#cancel').click(function (){
                    xhr.abort();
                })
            });
        </script>
    </body>
</html>
2 голосов
/ 08 августа 2011

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

1) пометить изображения, которые вы хотите загрузить

$(".image").each( function(){
    if ( is_in_visible_area(this) ) { // check [1] for example
        $(this).addClass("load_me");
    } else {
        $(this).addClass("dont_load");
    }
});

2) загрузка изображений

ajax_requests = {};

$(".image.load_me").each( function(){
    // load image
    var a = $.ajax({
        url: 'give_me_photos.php',
        data: {img: photo_id},
        success: function(html){
            photo_by_id(photo_id), img.append(html);
        }
    });
    ajax_requests[photo_id] = a;

});

3) отменить загрузку тех, кто находится вне экрана

for( id in ajax_requests ) {
    if ( ! is_in_visible_area(id) ) {
        ajax_requests[id].abort();
    }
}

Конечно, добавьте также некоторые проверки, если изображение уже загружено (например, класс "загружен")

[1]. Проверить, виден ли элемент после прокрутки

[2]. Прервать Ajax-запросы, используя jQuery

1 голос
/ 10 августа 2011
  1. Использование стека для управления запросами AJAX (означает, что у вас будет последовательная загрузка вместо параллельной, но это того стоит)

  2. При остановке прокрутки дождитесь300 мс, а затем помещать все изображения в области просмотра в стек

  3. Каждый раз, когда пользователь прокручивает, проверяет, работает ли стек.(к вашему сведению - вы можете остановить все запросы к определенному URL-адресу вместо того, чтобы убивать все вызовы AJAX. Также вы можете использовать регулярное выражение, чтобы оно не останавливало другие запросы на странице)

  4. Еслиработает существующий стек - извлеките все находящиеся в нем изображения, кроме самого верхнего.

  5. При всех вызовах ajax - связывайте событие beforeSend (), чтобы удалить это конкретное изображение из стека

Сейчас уже поздно, но мы сделали нечто очень похожее на работе - если вам нужен подробный код, дайте мне знать.

Приветствия!

0 голосов
/ 02 июня 2017

Решением может быть веб-работник.веб-работник может быть прекращен и с ним связь.Но есть небольшая проблема в том, что веб-работник использует ограниченные соединения браузера, поэтому приложение будет заблокировано.

Сейчас я работаю над решением с помощью serviceWorkers - у них нет ограничения на соединение (Я надеюсь на это)

0 голосов
/ 13 августа 2011

Может быть, вы могли бы передать изображение через скрипт php, который проверял бы поле в БД (или, что еще лучше, memcached), которое указывало бы на прекращение загрузки. скрипт будет разбивать изображение на части и делать паузу между ними и проверять, установлен ли флаг остановки для конкретного запроса. Если он установлен, вы отправляете заголовок с A 204 без содержимого, которое, как только браузер получает, перестает получать.

Хотя это может быть немного убито.

0 голосов
/ 10 августа 2011

Кстати, еще одна идея, которая может работать:

1) создать новый iframe

2) внутри iframe есть скрипт, который начинает загрузку изображения, и после его загрузки вызовите метод .parent

3) при необходимости остановите загрузку содержимого iframe с помощью .stop на объекте iframe

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...