【问题标题】:JavaScript - lazy-loading image fallbacks don't appear on iOS11 SafariJavaScript - 延迟加载图像后备不会出现在 iOS11 Safari 上
【发布时间】:2019-06-17 16:14:30
【问题描述】:

我创建了一个脚本,它利用带有 webp 和 jpg 后备的元素以及一些延迟加载来提供非常高质量的图像。到目前为止,它在除 iOS11 Safari 之外的所有“现代”浏览器中都能完美运行。

我已经为 IntersectionObserver 实现了一个回退,因为我知道这还不完全受支持,它使用 getClientBoundingRect() 来查找视口中图像的位置。我检查了 iOS 10、11,然后将其中一台相同的设备升级到开始加载图像的 iOS 12。

<div class="lazy-container">
            <picture class="lazy-thumbnail">
                <source srcset="{{ asset( '/images/media/placeholders/3.webp' ) }}" type="image/webp">
                <source srcset="{{ asset( '/images/media/placeholders/3.jpg' ) }}" type="image/jpeg">
                <img class="" src="{{ asset( '/images/media/placeholders/3.jpg' ) }}" />
            </picture>
            <picture data-lazy>
                <source data-srcset="{{ asset( '/images/media/3.webp' ) }}" type="image/webp">
                <source data-srcset="{{ asset( '/images/media/3.jpg' ) }}" type="image/jpeg">
                <img class="" src="{{ asset( '/images/media/3.jpg' ) }}" />
            </picture>
        </div>
const lazyObserver = new IntersectionObserver( ( entries, observer ) => {
            // Break into function to allow immediate calling
            const exchangeImage = ( image, source ) => {
                source.forEach( ( s ) => {
                    s.setAttribute( 'srcset',
                        s.getAttribute( 'data-srcset' ) );
                });
                image.previousElementSibling.classList.remove( 'lazy-thumbnail' );
                image.previousElementSibling.classList.add( 'ex-lazy-thumbnail' );
                image.classList.add( 'ex-lazy' );
                image.removeAttribute( 'data-lazy' );
                // If the image is in view and src has been swapped out, stop observing the image
                lazyObserver.unobserve( image );
            };
            entries.forEach( ( entry ) => {
                const image = entry.target;
                const source = image.querySelectorAll( 'source' );
                // If the image is either in view or data-lazy='immediate', load the image.
                if( entry.target.dataset.lazy === 'immediate' || entry.isIntersecting ){
                    exchangeImage( image, source );
                }
            });
        });

图片元素应该通过并加载适用于浏览器的第一个图像srcset,大多数情况下是webp,然后选择这些,当图像在视图中时,JS应该运行,将srcset换成data-srcset与大图像和负载。这适用于所有浏览器,除了

.lazy-container {
  overflow: hidden;
  position: relative;

  picture {
    width: 100%;
    position: absolute;
    top: 0;
    left: 0;

    img {
      display: block;
      width: 100%;
      height: auto;
    }
  }
}
.ex-lazy {
  filter: blur(0px);
  transition: all 500ms ease-in-out;
}
.lazy-thumbnail {
  opacity: 1;
  filter: blur(8px);
  transition: all 500ms ease-in-out;
  z-index: 1;
}
.ex-lazy-thumbnail {
  opacity: 0;
  filter: blur(0px);
  transition: all 500ms ease-in-out;
  z-index: 0;
}
[data-lazy]{
  width: 100%;
  height: auto;
  filter: blur(8px);
  transition: all 500ms ease-in-out;
}

【问题讨论】:

    标签: javascript ios safari lazy-loading ios11


    【解决方案1】:

    我以自己的方式解决了这个问题。 也看看polyfill能帮到吗polyfill

    let images = document.querySelectorAll('source, img');
    
    if ('IntersectionObserver' in window) {
      // we check if IntersectionObserver is supported by our browsers
      let config = {
        root: null,
        rootMargin: '0px',
        threshold: 0.5
      };
    
      let observer = new IntersectionObserver(onChange, config);
      images.forEach(function (img) { observer.observe(img) });
    
      function onChange(changes, observer) {
        changes.forEach(function (change) {
          if (change.intersectionRatio > 0) {
            // we stop observing and loading pictures
            loadImage(change.target);
            observer.unobserve(change.target);
          }
        });
      }
    
    } else {
      // if IntersectionObserver is not supported, we load all photos
      images.forEach(function (image) { loadImage(image) });
    }
    
    function loadImage(image) {
      image.classList.add('fade-in');
      if (image.dataset && image.dataset.src) {
        image.src = image.dataset.src;
      }
    
      if (image.dataset && image.dataset.srcset) {
        image.srcset = image.dataset.srcset;
      }
    }
    
    
    // -- How to add polyfil
    
    const modernBrowser = ('IntersectionObserver' in window);
    
    if (!modernBrowser) {
      loadScripts([
        "./polyfills/intersection-observer.js"
      ])
    }
    
    function loadScripts(array, callback) {
      var loader = function (src, handler) {
        var script = document.createElement("script");
        script.src = src;
        script.onload = script.onreadystatechange = function () {
          script.onreadystatechange = script.onload = null;
          handler();
        }
        var head = document.getElementsByTagName("head")[0];
        (head || document.body).appendChild(script);
      };
      (function run() {
        if (array.length != 0) {
          loader(array.shift(), run);
        } else {
          callback && callback();
        }
      })();
    }
    <picture>
      <source media="(min-width: 400px)" data-srcset="https://place-hold.it/400x400/15252D/fff">
      <source media="(min-width: 200px)" data-srcset="https://place-hold.it/200x200/15252D/fff">
      <img data-src="https://place-hold.it/100x100/15252D/fff">
      <noscript><img src="https://place-hold.it/100x100/15252D/fff"></noscript>
    </picture>

    Working code

    【讨论】:

    • 发挥了魅力,老实说不敢相信我是个白痴并且严重地想多了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多