如何仅在视口中加载图像?

Col*_*lin 15 javascript jquery

我现在看到很多网站,主要是有大量图片的教程网站,一旦进入视口,他们只会在页面下方加载图片?

我该怎么做呢?

一个例子:

http://www.chopeh.com/blog/logo-design-start-to-finish/

向下滚动页面时,视口下方的图像会淡入

Cir*_*四事件 29

<img loading="lazy" 没有任何Javascript

我们现在越来越多地支持这种标准化的非 JavaScript 方法,这非常令人兴奋!

您可以在下面的代码片段中看到这一点。

要查看加载实际上是延迟的,在“网络”选项卡中打开Chrome DevTools

然后,当您向下滚动代码段时,您将看到图像仅在您看到它们时加载。

我还添加了一个可选的 JavaScript 按钮,以表明您可以从 JavaScript更改lazy回默认值eager,然后图像将立即开始加载。

document.getElementById('load-now').addEventListener('click', function(){
  for (const img of document.getElementsByTagName('img')) {
    img.loading = 'eager';
  }
});
Run Code Online (Sandbox Code Playgroud)
.separator {
    height: 1000px;
    width: 100px;
    border: 5px solid red;
}
img {
    height: 340px;
    border: 5px solid black;
}
  #load-now {
  border: 5px solid black;
  }
Run Code Online (Sandbox Code Playgroud)
<div id="load-now">Click me to load all images now!</div>
<div><img loading="lazy" height="340" src="https://upload.wikimedia.org/wikipedia/commons/5/56/Donald_Trump_official_portrait.jpg"></div>
<div class="separator"></div>
<div><img loading="lazy" height="340" src="https://upload.wikimedia.org/wikipedia/commons/8/8d/President_Barack_Obama.jpg"></div>
<div class="separator"></div>
<div><img loading="lazy" height="340" src="https://upload.wikimedia.org/wikipedia/commons/d/d4/George-W-Bush.jpeg"></div>
<div class="separator"></div>
<div><img loading="lazy" height="340" src="https://upload.wikimedia.org/wikipedia/commons/d/d3/Bill_Clinton.jpg"></div>
<div class="separator"></div>
<div><img loading="lazy" height="340" src="https://upload.wikimedia.org/wikipedia/commons/9/90/George_H._W._Bush%2C_President_of_the_United_States%2C_1989_official_portrait_%28cropped%29.jpg"></div>
<div class="separator"></div>
<div><img loading="lazy" height="340" src="https://upload.wikimedia.org/wikipedia/commons/1/16/Official_Portrait_of_President_Reagan_1981.jpg"></div>
Run Code Online (Sandbox Code Playgroud)

这种方法的一个很酷的事情是它完全对 SEO 友好,因为该src=属性像往常一样包含图像源,另请参阅:带有语义标记的延迟图像加载

在 Chromium Chromium 81 和 Firefox 77.0.1 中测试,都可以正常工作并延迟加载。

IntersectionObserver 最小的可运行示例

这是一种在img loading="lazy"实现之前可以工作的 JavaScript 方法。

这基本上是使用的技术:https : //appelsiini.net/projects/lazyload/提到的技术:https : //stackoverflow.com/a/2322042/895245

Web API 现在已经发展了很多,从头开始编写它并不难!

var observer = new IntersectionObserver(
    (entries, observer) => {
        entries.forEach(entry => {
            if (entry.intersectionRatio > 0.0) {
                img = entry.target;
                if (!img.hasAttribute('src')) {
                    alert('will load the image!!!');
                    img.setAttribute('src', img.dataset.src);
                }
            }
        });
    },
    {}
)
for (let img of document.getElementsByTagName('img')) {
    observer.observe(img);
}
Run Code Online (Sandbox Code Playgroud)
.separator {
    height: 1000px;
    width: 100px;
    border: 5px solid red;
}
img {
    height: 340px;
    border: 5px solid black;
}
Run Code Online (Sandbox Code Playgroud)
<div><img data-src="https://upload.wikimedia.org/wikipedia/commons/5/56/Donald_Trump_official_portrait.jpg"></div>
<div class="separator"></div>
<div><img data-src="https://upload.wikimedia.org/wikipedia/commons/8/8d/President_Barack_Obama.jpg"></div>
<div class="separator"></div>
<div><img data-src="https://upload.wikimedia.org/wikipedia/commons/d/d4/George-W-Bush.jpeg"></div>
<div class="separator"></div>
<div><img data-src="https://upload.wikimedia.org/wikipedia/commons/d/d3/Bill_Clinton.jpg"></div>
<div class="separator"></div>
<div><img data-src="https://upload.wikimedia.org/wikipedia/commons/9/90/George_H._W._Bush%2C_President_of_the_United_States%2C_1989_official_portrait_%28cropped%29.jpg"></div>
<div class="separator"></div>
<div><img data-src="https://upload.wikimedia.org/wikipedia/commons/1/16/Official_Portrait_of_President_Reagan_1981.jpg"></div>
Run Code Online (Sandbox Code Playgroud)

整页演示:https : //cirosantilli.com/web-cheat/js-image-load-viewport.html

GitHub 上游:https : //github.com/cirosantilli/cirosantilli.github.io/blob/1f637bf4791b115777300f48f427f0a6bb409fc1/web-cheat/js-image-load-viewport.html

该技术只是以下各项的组合:

在铬 76 中测试。

将加载顺序更改为最近的优先

这是loading="lazy"我缺少的最后一个用例:一种急切下载的方法,但将下载顺序更改为首先在视口上下载,然后在下方,然后在上方:更改页面上已有图像的加载顺序

也许我们可以做点什么querySelectorAll()来解决jQuery 查找某个类的 next/prev 元素但不一定是兄弟的问题,然后loading=lazy从 JavaScript 中的图像中删除!这既会优雅地降级,又会对 SEO 友好。

最后一个问题是如何获取第一个可见元素:

我还没有看到一个很好的解决方案。

延迟加载视频

不知道为什么,但无论是 Chromium 81 还是 Firefox 77.0.1 都不能延迟加载视频,现在确定他们为什么这样做只是为了img

iframe然而,Chromium 81 确实实现了它,这是 YouTube 嵌入使用的,而 Firefox 77.0.1 没有:使用 jquery 延迟加载 iframe(延迟 src http 调用)


z5h*_*z5h 15

http://www.appelsiini.net/projects/lazyload
https://github.com/tuupola/jquery_lazyload

演示:http:
//www.appelsiini.net/projects/lazyload/enabled.html

  • 看起来这个项目还活着(再次).它也在GitHub上:https://github.com/tuupola/jquery_lazyload. (2认同)

Cer*_*rin 12

用占位符替换图像(例如,只需将"src"属性更改为其他内容,以便图像不会加载,但仍然可以访问该URL),然后将窗口滚动事件绑定到将查找所有图像的函数当前滚动位置,并将图像src交换为真正的img标记.

这是代码.这是未经测试的,但这应该是基本的想法:

<img src="" realsrc="/myimage.png" />

$(document).ready(function(){

  $(window).scroll(function(){
    $('img[realsrc]').each(function(i){
      var t = $(this);
      if(t.position().top > ($(window).scrollTop()+$(window).height()){
        t.attr('src', t.attr('realsrc')); // trigger the image load
        t.removeAttr('realsrc'); // so we only process this image once
      }
    });
  })

});
Run Code Online (Sandbox Code Playgroud)


Len*_*oyt 11

不依赖于JQuery的简单解决方案:

    <script type="text/javascript">
        refresh_handler = function(e) {
        var elements = document.querySelectorAll("*[realsrc]");
        for (var i = 0; i < elements.length; i++) {
                var boundingClientRect = elements[i].getBoundingClientRect();
                if (elements[i].hasAttribute("realsrc") && boundingClientRect.top < window.innerHeight) {
                    elements[i].setAttribute("src", elements[i].getAttribute("realsrc"));
                    elements[i].removeAttribute("realsrc");
                }
            }
        };

        window.addEventListener('scroll', refresh_handler);
        window.addEventListener('load', refresh_handler);
        window.addEventListener('resize', refresh_handler);
    </script>
Run Code Online (Sandbox Code Playgroud)

  • 它工作得很棒!顺便说一下,你必须在HTML中替换所有出现的`<img rel="nofollow noreferrer" src ="/ myimage.png"/>`(在答案中没有注明):`<img rel="nofollow noreferrer" src =""realsrc ="/ myimage.png"/>`如果你想避免IDE的任何警告,请使用`data-src`而不是`realsrc`(也可以在javascript中替换它) (3认同)
  • 什么部分要求浏览器相当新?似乎完全支持getBoundingClientRect. (2认同)
  • 您可能也希望绑定到'resize'事件 (2认同)

归档时间:

查看次数:

16074 次

最近记录:

6 年,3 月 前