大数跨境
0
0

借助图片懒加载触发 JavaScript 动态导入

借助图片懒加载触发 JavaScript 动态导入 前端技术编程
2025-12-08
2

近年来 html 的最好改进之一是你可以添加到图像(也包括 iframe)的 loading="lazy" 属性,它将告诉浏览器直到图像出现在视口才加载图像。

  <img src="/images/your-image.png" loading="lazy">

非常简单,非常实用。但如果你也能对脚本做同样的事情,那该多好。这样你就可以懒加载你的组件,只有当它们实际需要时才加载...

嗯, <img> 元素还有另一个功能,就是使用 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 模块支持几乎已经普及,我们可以使用非常强大的事件导入后默认 javascript 加载技术来在事件触发后加载脚本,如下所示:

<img     src="data:,"     loading="lazy"    onerror="import('/js/some-component.js').then(_ => _.default(this))">

注意:这也适用于 onclick 、 onchange 等事件。

注意:下划线只是访问模块的简写方式,你也可以写成 .then(Module => Module.default(this))

好了,这里到底是怎么回事!?

首先让我们看看 some-component 可能的样子:

// some-component.js
export default element => {    element.outerHTML = `        <div class="whatever">            <p>Hello world!</p>        </div>    `;}

所以,你可能已经注意到,在 onerror 回调中,我将 this 作为参数传递给了默认导出。我这样做的原因(抱歉用词不当😁)是为了给调用它的脚本提供 <img> ,因为在当前(我又犯错了🤦)的上下文中 this = <img> 。

现在你可以简单地 element.outerHTML 替换损坏的图片为你自己的 HTML 标记,然后你就有了懒加载的脚本!😱

缓存和传递参数

如果,您在页面上多次使用此技术,那么您需要向 data:, 传递一个"缓存破坏"索引,或随机数,例如:

<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 传递给了函数,你可以像这样访问 data 属性:

export default element => {    const { message } = element.dataset    element.outerHTML = `        <div class="whatever">            <p>${message}</p>        </div>    `;}
最后,推荐国内性价比最高的一款镜像AI系统,一站搞定全球六大顶级的AI工具,包含以下所有的AI模型:
☑ GPT5.1/GPT5.1 Thinking系列模型
☑ Gemini-3.0-Pro
☑ Claude 4.5大模型
☑ 满血版DeepSeek-V3.2/R1大模型
☑ Sora 2 视频大模型
☑ Nano banana Pro 画图
☑ Midjourney 7.0绘画
☑ Grok 4.1/Grok 4模型
☑ Kimi和codex模型 
☑ Google-Veo3.1视频模型
☑ 即梦 4.0图片/视频
☑ 其它主流AI模型
图片
国内可用!一站式搞定顶尖的六大AI工具
全网疯传的 ClaudeCode,3000 字保姆级教程 !
一键秒充官网 ChatGPT Plus 教程,国内直接到账 !

【声明】内容源于网络
0
0
前端技术编程
专注于分享前端技术:JS,HTML5,CSS3,Vue.js,React,Angular 等前端框架和前端开源项目推荐!
内容 1148
粉丝 0
前端技术编程 专注于分享前端技术:JS,HTML5,CSS3,Vue.js,React,Angular 等前端框架和前端开源项目推荐!
总阅读86
粉丝0
内容1.1k