如何点击显示图片

Avatar of Robin Rendle
Robin Rendle

DigitalOcean 为您的旅程的每个阶段提供云产品。 立即开始使用 $200 的免费信用额度!

网络上大多数图片都是多余的。 如果你能忍受我当一会儿坏人,99% 的图片甚至都没有那么有用 (尽管有一些罕见的例外). 这是因为图片通常不能很好地补充它们应该支持的文本,反而会损害用户,加载时间过长,还会像某种性能税一样耗尽数据上限。

谢天谢地,如今这主要是一个设计问题,因为让图片更有效率,更方便用户使用比以前容易得多。 我们有更好的图片格式,比如 WebP (很快,也许还有 JPEG XL). 我们当然也有 响应式图片 的魔法。 而且还有很多很棒的工具,比如 ImageOptim,以及像 Addy Osmani 的新书 这样的资源。

尽管也许我最喜欢的提高图片性能的方式是使用 延迟加载

<img href="image.webp" alt="Image description" loading="lazy">

这张图片只有在用户滚动到页面下方,图片进入用户视野时才会加载——这样就可以将其从初始页面加载中移除,这简直太好了! 让网页的初始加载速度变得极快非常重要。

但也许有些图片根本不应该加载。 也许在某些情况下,最好让用户选择是否查看图片。 例如,可以查看 NPR 的纯文本版本,四处点击一下。 它是不是… 很棒? 它很易读! 没有任何杂乱无章的东西,它尊重我作为用户,而且——太棒了——它很快

我是不是刚刚在你一篇博客文章中展示了一张图片,这张图片侮辱了图片的概念? 是的! 告我吧。

所以! 如果我们可以在网站上显示图片,但只在点击或轻触时显示呢? 如果我们可以在点击时用真实图片替换占位符,那不是很有趣吗? 就像这样

嗯,我在这里有两个想法,关于如何构建这个小家伙(黄金法则是有很多方法可以构建网络上的任何东西)。

方法 #1:使用<img> 但不使用src 属性

我们可以移除<img> 标签的src 属性来隐藏图片。 然后可以将图片文件放在某个属性中,比如data-src 或其他类似属性,就像这样

<img data-src="image.jpg" src="" alt="Photograph of hot air balloons by Musab Al Rawahi. 144kb">

默认情况下,大多数浏览器会显示一个你可能熟悉的损坏图片图标

好吧,它某种程度上是可访问的。 我猜? 你可以看到alt 标签自动渲染在屏幕上,但使用少量 JavaScript,我们就可以用该属性替换src

document.querySelectorAll("img").forEach((item) => {
  item.addEventListener("click", (event) => {
    const image = event.target.getAttribute("data-src");
    event.target.setAttribute("src", image);
  });
});

现在我们可以添加一些样式,哦,不

Ugh. 在某些浏览器中,当图片未加载时,底部会显示一个小的损坏图片图标。 这里的问题是,浏览器不提供使用 CSS 移除损坏图片图标的方法(而且我们可能也不应该被允许这样做)。 对alt 文本进行样式设置也很烦人。 但如果我们完全删除alt 属性,那么损坏图片图标就会消失,尽管这样会使<img> 在没有 JavaScript 的情况下无法使用。 所以,移除alt 文本不可行。

正如我所说:Ugh. 我认为没有办法使这种方法起作用(但请证明我错了!)。

我们拥有的另一个选项是使用普通的超链接,就像这样

<a href="image.jpg">Photograph of hot air balloons by Musab Al Rawahi. 144kb<a>

是的,还没有什么智能的功能——这只会渲染一个指向图片的链接

从可访问性角度来看,这没问题,对吧? 如果我们没有 JavaScript,我们只有一个人可以选择点击的链接。 从性能角度来看,它不可能比纯文本更快!

但从这里开始,我们可以使用 JavaScript 来阻止链接在点击时加载,获取链接中的href 属性,创建一个图片元素,最后将该图片放到页面上,并在完成后删除旧链接

document.querySelectorAll(".load-image").forEach((item) => {
  item.addEventListener("click", (event) => {
    const href = event.target.getAttribute("href");
    const newImage = document.createElement("img");
    event.preventDefault();
    newImage.setAttribute("src", href);
    document.body.insertBefore(newImage, event.target);
    event.target.remove();
  });
});

我们可以对这个占位符链接进行样式设置,使其看起来比下面显示的样式更漂亮。 但这只是一个例子。 点击链接再次加载图片

就是这样! 它并不突破性,而且我相信在某个时候有人做过类似的事情。 但如果我们想在第一次绘制和初始加载之外,对性能进行非常彻底的改造,我认为这是一个不错的解决方案。 如果我们要创建一个纯文本网站,我认为这绝对是最佳选择。

也许我们还可以用它创建一个 Web 组件,甚至可以检测用户是否启用了 prefers-reduced-data,然后只有当用户有足够的数据时才会加载图片。 你觉得怎么样?