Ленивая загрузка IMG с IntersectionObserver polyfill не удается в Internet Explorer - PullRequest
0 голосов
/ 31 мая 2018

Я пытаюсь реализовать отложенную загрузку изображений с помощью IntersectionObserver, где это возможно, и с помощью полизаполнения в противном случае (как рекомендуется здесь ).

+function ($, window, document, undefined) {
    var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

var lazyLoadImage = function() {
    var lazyImageObserver = new IntersectionObserver(function(entries, observer) {
        entries.forEach(function(entry) {
            if (entry.isIntersecting) {
                var lazyImage = entry.target;
                lazyImage.src = lazyImage.dataset.src;
                lazyImage.classList.remove("lazy");
                lazyImageObserver.unobserve(lazyImage);
            }
        });
    });

    lazyImages.forEach(function(lazyImage) {
        lazyImageObserver.observe(lazyImage);
    });
};

var lazyLoadImagePolyfill = function() {
    var active = false;

    if (active === false) {
        active = true;

        setTimeout(function() {
            lazyImages.forEach(function(lazyImage) {
                if ((lazyImage.getBoundingClientRect().top <= window.innerHeight
                     && lazyImage.getBoundingClientRect().bottom >= 0)
                     && getComputedStyle(lazyImage).display !== 'none') {
                         console.log('lazyImage:', lazyImage);
                         lazyImage.src = lazyImage.dataset.src;
                         lazyImage.classList.remove('lazy');

                         lazyImages = lazyImages.filter(function(image) {
                             return image !== lazyImage;
                         });

                        if (lazyImages.length === 0) {
                            document.removeEventListener('scroll', lazyLoadImagePolyfill);
                            window.removeEventListener('resize', lazyLoadImagePolyfill);
                            window.removeEventListener('orientationchange', 
                            lazyLoadImagePolyfill);
                    }
                }
            });
            active = false;
        }, 200);
    }
    document.addEventListener("scroll", lazyLoadImagePolyfill);
    window.addEventListener("resize", lazyLoadImagePolyfill);
    window.addEventListener("orientationchange", lazyLoadImagePolyfill);
};

document.addEventListener('DOMContentLoaded', function(){
    if ("IntersectionObserver" in window) {
        lazyLoadImage();
    } else {
        lazyLoadImagePolyfill();
    }
});
}(jQuery, window, document)

Этот подход работал правильново всех браузерах, которые я тестировал, кроме IE.Я получаю SCRIPT5007: Unable to get property 'src' of undefined or null reference в консоли;строка, которая выдает ошибку - lazyImage.src = lazyImage.dataset.src;.Однако console.log, предшествующий этой строке, показывает следующее:

lazyImage: [object HTMLImageElement]
    "lazyImage:"
    <img class="lazy" src="placeholder.png" data-src="real-pic.jpg"></img>

Обратите внимание: меня попросили не использовать внешнюю библиотеку или плагин.Есть идеи, почему это происходит и как это исправить?

1 Ответ

0 голосов
/ 31 мая 2018

Я обычно использую в поле зрения для такого рода вещей, когда я не могу использовать наблюдателей, но вы сказали, что вас попросили не использовать какую-либо внешнюю библиотеку или плагин, поэтому я написал вамэтот код в ванильном JavaScript.Этот код будет работать в IE9 = <без полизаполнений. </p>

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

document.addEventListener('DOMContentLoaded', lazyLoadImagePolyfill);

function lazyLoadImagePolyfill() {
  var lazyLoadImages = Array.from(document.getElementsByClassName('lazy'));
  _loadImage();
  window.onscroll = _loadImage;

  function _loadImage() {
    for (let i = 0; i < lazyLoadImages.length; i += 1) {
      var img = lazyLoadImages[i];
      if (isVisible(img)) {
        showImage(img);
      }
    }
  }
}

function isVisible(element) {
  var {
    top,
    bottom
  } = element.getBoundingClientRect();
  var vHeight = (window.innerHeight || document.documentElement.clientHeight);
  return ((top > 0 || bottom > 0) && top < vHeight);
}

function showImage(img) {
  var src = img.getAttribute('data-src');
  if (!src) {
    return;
  }
  img.setAttribute('src', src);
  img.onload = function() {
    img.removeAttribute('data-src');
  };
}
img {
  margin-bottom: 200px;
  min-height: 1px;
  width: 100%;
  display: block;
}

.container {
  display: flex;
  flex-wrap: wrap;
  width: 400px;
  margin: auto;
}
<div class="container">
  <img class="lazy" data-src="http://www.facetheforce.today/han-old/400" alt="Han Solo Old">
  <img class="lazy" data-src="http://www.facetheforce.today/han/400" alt="Han Solo">
  <img class="lazy" data-src="http://www.facetheforce.today/luke-old/400" alt="Luke Old">
  <img class="lazy" data-src="http://www.facetheforce.today/luke/400" alt="Luke">
  <img class="lazy" data-src="http://www.facetheforce.today/han-old/400">
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...