如何在点击时显示图片

224 阅读4分钟

网络上的大多数图片都是多余的。如果我是个混蛋的话,99%的图片根本就没有什么帮助(尽管有极少数的例外)。这是因为图片往往不能补充它们应该支持的文本,反而会伤害用户,需要永远加载,并像某种性能税一样炸毁数据上限。

值得庆幸的是,今天这主要是一个设计问题,因为使图像的性能和用户友好性比以前容易得多。我们有更好的图像格式,如WebP(也许很快还有JPEG XL)。当然,我们还有神奇的响应式图像。还有大量伟大的工具,如ImageOptim,以及Addy Osmani的新书等资源。

不过,我最喜欢的提高图片性能的方法也许是用懒人加载

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

这张图片只有在用户向下滚动页面时才会加载,这样用户就可以看到它了--这就把它从最初的页面加载中移除,这实在是太好了让网页的初始加载速度快如闪电是一件大事。

但是,也许有些图像根本就应该加载。也许在有些情况下,如果一个人可以选择看到它,那就更好了。这里有一个例子:利用NPR的纯文本版本,点击一下。这不是......很好吗?它是可读的!它没有到处都是的垃圾,它尊重我这个用户,而且--甜蜜的上帝--它的速度很快

我刚刚给你看了一篇侮辱图片概念的博客文章中的图片吗?是的!是的。告我吧。

那么!如果我们可以在网站上显示图片,但只在它们被点击后才显示呢?如果我们可以显示一个占位符,并在点击时将其换成真正的图片,这不是很好吗?就像这样。

好吧,我有两种想法,即如何建立这一章(黄金法则是,在网络上建立任何东西都没有一种方法)。

方法#1:使用没有src 属性的<img>

我们可以删除<img> 标签的src 属性来隐藏图像。然后,我们可以把图像文件放在一个属性中,如data-src 或其他,就像这样。

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

默认情况下,大多数浏览器会显示一个破损的图像图标,你可能已经很熟悉了。

CodePen嵌入回退

好的,所以它算是可以访问的。我猜?你可以看到alt 标签在屏幕上自动呈现,但用一个轻巧的JavaScript,我们就可以把src 与该属性对调。

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

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

糕。在一些浏览器中,当图像没有加载时,底部会有一个微小的破碎图像图标。这里的问题是,浏览器没有给你一个方法,用CSS来移除破碎的图像图标(反正我们可能不应该被允许这样做)。样式化的alt 文本也有点烦人。但如果我们完全删除alt 属性,那么破损的图像图标就没有了,尽管这使得<img> 在没有JavaScript的情况下无法使用。所以删除那个alt 文本是不可能的。

正如我所说。。我不认为有什么方法可以使这个方法有效(尽管请证明我是错的!)。

方法二:使用链接来创建一个图像

我们的另一个选择是用简陋的超链接开始,像这样。

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

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

也许我们还可以把它做成一个网络组件,或者甚至可以检测到某人是否有prefers-reduced-data然后只在有人有足够的数据时才加载图片,或者其他什么。你有什么想法?