当前位置: 首页 > 知识库问答 >
问题:

JavaScript-延迟加载图像回退不会出现在iOS11 Safari上

罗昕
2023-03-14

我创建了一个脚本,它利用webp和jpg回退元素以及一些延迟加载来提供非常高质量的图像。到目前为止,除了iOS11Safari,它在每个“现代”浏览器中都可以完美运行。

我已经实现了一个回退的交叉点观察者,因为我知道这是不完全支持的,它使用getClientBoundingRect()找到图像在视口中的位置。我检查了iOS10,11,然后将其中一个设备升级到iOS12,图像开始加载。

<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;
}

共有1个答案

秦焱
2023-03-14

我用我的方式解决了这个问题。也看一下聚填料可以帮助聚填料

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>
 类似资料:
  • 我正在使用Mika Tuupola的jQuery延迟加载。 是否可以在每次延迟加载图像后调用函数。 我打算做的是跟踪图像的浏览次数。因此,如果图像是延迟加载的,这意味着用户已经看到了图像,我将通过在后台执行HTTP GET,将数据库中的计数器增加1。

  • 我似乎不能为我的生活得到任何图像懒惰加载插件在wordpress工作。我尝试了懒负载,wp懒负载和bj懒负载。网站上的图像似乎没有一个是“懒惰加载”的。我也使用审计工具(chrome审计)测试了这个。当我删除图像(每页大约有50张图像)时,我的审计绩效和其他分数为99。当我加载图像(使用wordpress循环),我的性能下降到64. 我尝试了每一个延迟加载插件,但它们似乎都不是延迟加载。我正在本地

  • 我试图使用jQuery懒惰加载在我的Laravel/Vue项目,但我正在努力让图像出现在我的Vue组件。我有以下img块,我认为会工作: 我确实在这里发现了另一个问题-Vue.js模板中的静态图像src-但是当我尝试该方法时,我得到了这样的结果: 因此,我切换回v-bind方法,但我得到的只是一个带有灰色边框的白色框-没有图像。但是,如果我在src属性上使用v-bind,我可以正确地看到图像。 我

  • 我想做一个reactjs页面懒惰加载图像。因此,我调用lazyLoadImages()内部的组件didMount()。我发现位于浏览器选项卡的浏览器加载指示器仍然一路旋转,直到加载所有图像。这让我认为我所做的并没有提供真正的懒惰加载图像体验。 有趣的是,如果我在setTimeout中用一个不太短的timeout参数包装lazyLoadImages(),例如100ms(不是0或甚至50ms),那么页

  • 问题是:PageSpeedInsights说图像没有被延迟加载,留档说img标签应该被“data-page espeed-laily-src”属性替换(它没有这样做)。 pagespeed.conf: 超文本标记语言: 它正在转换png图像,我看到了“X-Mod-Pagespeed”标题,所以我确信模块在那里。 /pagespeed_admin显示“Lazyload Images”过滤器已启用。o

  • 我正在使用这个插件jQuery延迟内容、图像和背景延迟加载程序 我尝试在延迟加载后向图像添加图像边框颜色和图像边框厚度,但似乎没有效果。若我在开发者控制台按“inspect”,我可以看到这个属性被添加到图像样式中,但它的效果并没有显示在屏幕上。 超文本标记语言 JQuery