近年来对 html 的最佳改进之一是 loading="lazy" 属性,您可以将其添加到图像(也包括 iframe)中,该属性将告诉浏览器不要加载图像直到出现在视口中。
<img src="/images/your-image.png" loading="lazy">
非常简单,非常有用。但如果您也可以对脚本执行此操作,那就太好了。这样你就可以延迟加载你的组件,只有当它们确实需要时......
嗯,另一个特点是元素具有以下功能:在图像使用 onload 和 onerror 属性加载(或不加载)之后运行脚本。
<img src="/images/your-image.png" loading="lazy" onload="() => console.log('image loaded')" >
此 onload“回调”仅在加载图像时才会触发,如果图像是延迟加载的,则仅当图像位于视口中时才会触发。瞧!延迟加载的脚本。
不幸的是,这样的东西并没有多大用处。首先,您的页面上会出现不需要的图像,其次,您需要内联要运行的 JavaScript,这有点违背了延迟加载的目的。因此,让我们做出一些改变来改进这一点。
图像本身可以是任何东西,或者更重要的是,什么都不是。正如我之前提到的,有一个 onerror 回调,顾名思义,当图像 未 加载时,它将触发。
这并不意味着您需要将 src 指向不存在的图像,这会导致控制台充满关于丢失图像的红色 404 错误,而没有人希望这样。
如果 src 图像实际上不是图像,也会触发 onerror 回调,最简单的方法是使用 data: 格式“错误地编码”图像。这还有一个好处,就是不会在控制台中填充丢失图像的警告?
<img src="data:," loading="lazy" onerror="() => console.log('image not loaded')" >
这仍然会导致页面出现“损坏的图像”缩略图,但我们会解决这个问题。
好的,但是我们仍然需要内联我们想要运行的 JavaScript,那么我们如何解决这个问题呢?
现在 ES 模块支持几乎是普遍的,我们可以使用非常强大的 event-import-then-default javascript 加载技术在事件触发后加载脚本,如下所示:
<img src="data:," loading="lazy" onerror="import('/js/some-component.js').then(_ => _.default(this))" >
注意:这也适用于 onclick、onchange 等事件
注意:下划线只是访问模块的简写方式,你也可以写 .then(Module => Module.default(this))
好吧,那这是怎么回事!?
首先让我们看一下某些组件可能是什么样子:
// some-component.js export default element => { element.outerHTML = ` <div class="whatever"> <p>Hello world!</p> </div> `; }
所以,您可能已经注意到,在 onerror 回调中,我将其作为参数传递给默认导出。我这样做的原因这个(请原谅双关语?)是为了给脚本提供 。调用它,因为在 this (我又做了一次?)上下文 this =
。现在您可以简单地使用 element.outerHTML 用您的 html 标记替换损坏的图像,然后您就拥有了延迟加载的脚本! ?
如果您在一个页面上多次使用此技术,那么您需要向数据传递“缓存清除”索引或随机数:例如:
<img src="data:,abc123" loading="lazy" onerror="import('/js/some-component.js').then(_ => _.default(this))" > <img src="data:,xyz789" loading="lazy" onerror="import('/js/some-other-component.js').then(_ => _.default(this))" >
“:,”后面的字符串可以是任何内容,只要它们不同即可。
将参数传递给函数的一个非常简单的方法是在 html 中使用 data-something 属性,如下所示:
<img src="data:," loading="lazy" data-message="hello world" onerror="import('/js/some-component.js').then(_ => _.default(this))" >
由于我们将 this 传递给函数,您可以像这样访问数据属性:
export default element => { const { message } = element.dataset element.outerHTML = ` <div class="whatever"> <p>${message}</p> </div> `; }
请在评论中告诉我你的想法! ❤️
以上是延迟加载脚本,例如图像的详细内容。更多信息请关注PHP中文网其他相关文章!