it-swarm.com.ru

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

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

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

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

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

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

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

43
Evan

То, что вы пытаетесь сделать, - это неправильный подход, как упомянуто 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();
       }
    };
    
    });
    
17
Yanick Rochon

Ну, моя идея:

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>
12
Guard

Вы можете загружать изображения с помощью вызовов 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

2
Jakub M.
  1. Используйте стек для управления ajax-запросами (это означает, что у вас будет последовательная загрузка вместо параллельной, но это того стоит)

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

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

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

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

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

Ура!

1
Varun Vohra

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

Это может быть немного за убийство, хотя.

0
matthewdaniel

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

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

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

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

0
Guard

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

Прямо сейчас я работаю над решением с serviceWorkers - у них нет ограничения на соединение (я надеюсь, что так)

0
teter