返回课程

加载可见图像

重要性:4

假设我们有一个速度慢的客户端,想要节省他们的移动流量。

为此,我们决定不立即显示图像,而是用占位符替换它们,如下所示

<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">

因此,最初所有图像都是 placeholder.svg。当页面滚动到用户可以看到图像的位置时,我们将 src 更改为 data-src 中的图像,这样图像就会加载。

以下是在 iframe 中的示例

滚动它以查看图像“按需”加载。

要求

  • 页面加载时,屏幕上的图像应立即加载,先于任何滚动操作。
  • 一些图像可能是普通的,没有 `data-src` 属性。代码不应该触碰它们。
  • 一旦图像加载完成,在滚动进出时不应该重新加载。

附注:如果可以,请提供更高级的解决方案,可以“预加载”当前位置下方/之后一页的图像。

附注:仅处理垂直滚动,不处理水平滚动。

打开一个沙盒环境来完成任务。

`onscroll` 处理程序应该检查哪些图像可见并显示它们。

我们还希望在页面加载时运行它,以检测立即可见的图像并加载它们。

代码应该在文档加载完成后执行,以便它可以访问文档内容。

或者将其放在 `<body>` 标签的底部。

// ...the page content is above...

function isVisible(elem) {

  let coords = elem.getBoundingClientRect();

  let windowHeight = document.documentElement.clientHeight;

  // top elem edge is visible?
  let topVisible = coords.top > 0 && coords.top < windowHeight;

  // bottom elem edge is visible?
  let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;

  return topVisible || bottomVisible;
}

`showVisible()` 函数使用 `isVisible()` 实现的可见性检查来加载可见图像。

function showVisible() {
  for (let img of document.querySelectorAll('img')) {
    let realSrc = img.dataset.src;
    if (!realSrc) continue;

    if (isVisible(img)) {
      img.src = realSrc;
      img.dataset.src = '';
    }
  }
}

showVisible();
window.onscroll = showVisible;

附注:该解决方案还包含 `isVisible` 的变体,可以“预加载”当前文档滚动位置上下 1 页内的图像。

在沙盒环境中打开解决方案。