脚本喷出器
脚本注射器是一个自定义元素,旨在将脚本动态地加载到您的网页中. 它提供了根据某些条件和事件加载脚本的方法.
使用量
要使用脚本喷出器, 您需要将其包含在 HTML 中 :
<scripts-injector></scripts-injector>
Web 组件示例
装入闲置
<scripts-injector scripts="/analytics.js" on:idle>
<div>Content</div>
</scripts-injector>
装入交互
<scripts-injector scripts="/heavy-chart.js" on:interaction="mouseenter,focusin">
<button>Open chart</button>
</scripts-injector>
使用注射器地图加载
<scripts-injector>
<script type="ecopages/injector-map">
{
"on:idle": { "scripts": ["/_assets/tracker.js"] },
"on:interaction": {
"value": "click",
"scripts": ["/_assets/heavy-ui.js"]
}
}
</script>
<div class="my-component">...</div>
</scripts-injector>
全球注射器实例( 无网络组件)
(1) 定义全球触发图
<script type="ecopages/global-injector-map">
{
"analytics-trigger": {
"on:idle": { "scripts": ["/_assets/tracker.js"] }
},
"card-trigger": {
"on:interaction": {
"value": "click",
"scripts": ["/_assets/card-interactions.js"]
}
}
}
</script>
(2) 将标准元素与 data-eco-trigger
<div data-eco-trigger="analytics-trigger"></div>
<button data-eco-trigger="card-trigger">Open Card</button>
(3) 初始化
import { initGlobalInjector } from '@ecopages/scripts-injector/global';
const injector = initGlobalInjector();
// Call after SPA route changes / page swaps when new trigger-map tags or
// new [data-eco-trigger] elements are inserted by your framework.
injector.refresh();
// Call during app teardown if needed.
injector.cleanup();
initGlobalInjector() 返回控点,使用:
refresh()- 重新绘制所有全球地图,并将任何不受约束的元素与data-eco-triggercleanup()——断开观察器,并禁用进一步的刷新工作
道具
脚本喷出器类型定义了可用于控制脚本-喷出器自定义元素的行为的属性. 以下是可用的属性 :
"on:idle": 此可选布尔属性决定 DOM 准备好后是否应该加载脚本 。 譬如说, <scripts-injector on:idle></scripts-injector> dOM 准备好后, 立即装入脚本 .
"on:interaction": 此可选属性允许您指定一系列会触发脚本加载的事件 。 可以是"touchstart, click",也可以是"mouseenter, focusin". 譬如说, <scripts-injector on:interaction="mouseenter, focusin"></scripts-injector> 当用户在元素上方鼠标或聚焦时,会加载脚本.
"on:visible": 此可选属性可以是字符串或布尔 。 如果它是一个字符串,它应该指定一个截面观察器的根边距,当元素被看到时会加载脚本. 如果它是布尔并是真的,则当元素以默认的根边距被查看时,脚本会被加载. 譬如说, <scripts-injector on:visible="50px 1px"></scripts-injector> 将在元素进入视图时加载脚本,根边距为50px 1px.
scripts: 此属性应该是要装入的以逗号分隔的脚本字符串 。 譬如说, <scripts-injector scripts="script1.js,script2.js"></scripts-injector> 将载入脚本1.js和脚本2.js.
最新特征
完整事件与财产保存重放
对所有交互事件,脚本喷出器会截取初始事件,防止默认动作,加载所需的脚本,然后 重放该事件 并保留了所有原始财产。 这保证了用户动作永远不会丢失,即使它们在脚本被完全加载之前发生.
- 单击事件: 使用本地语言
.click()与链接和表格的最佳兼容性 - 鼠标事件: 保护
clientX, (中文(简体) ),clientY, (中文(简体) ),screenX, (中文(简体) ),screenY, (中文(简体) ),button, (中文(简体) ),buttons修改键 - 键盘事件: 保护
key, (中文(简体) ),code, (中文(简体) ),location, (中文(简体) ),repeat修改键 - 重点活动: 保护
relatedTarget - 触摸活动: 保护
touches, (中文(简体) ),targetTouches, (中文(简体) ),changedTouches修改键
种族条件预防
多个请求同一脚本的脚本注射器会协调以防止重复加载. 目前正在加载的静态注册脚本,确保即使多个注射器同时触发时,也只发出一个网络请求.
装入原因跟踪
装入后,元素收到 data-load-reason 属性表示触发负载的内容 :
idle- 装入on:idlevisible- 装入on:visibleinteraction:click, (中文(简体) ),interaction:mouseenter等 - 通过特定交互事件装入
跟踪错误
如果有任何脚本无法加载, 元素会收到一个 data-error 包含逗号分隔的失败脚本 URL 的属性。 这个 DATA_LOADED 事件还包括: failedScripts 详细排列.
// Listen for load completion with error info
document.addEventListener('data-loaded', (event) => {
const { loadedScripts, failedScripts } = event.detail;
if (failedScripts.length > 0) {
console.warn('Some scripts failed to load:', failedScripts);
}
});
典型用途
本段为自定义元素提供了一个标准用例. 脚本的设计是当用户通过鼠标条目或焦点事件与其互动时加载. 如果有多个脚本注射器使用相同的脚本,则只有第一个会执行负载. 这是因为一旦一个脚本被加载,所有脚本注射器都会被通知,并随后去除脚本的加载责任.
<scripts-injector on:interaction="mouseenter,focusin" scripts={['path/to/my/element']}>
<lit-counter class="lit-counter" count={8}></lit-counter>
</scripts-injector>
替代用法: 多调试器配置
避免深陷其中 <scripts-injector> 当单个组件内不同的脚本需要不同的触发器时,可以使用JSON映射配置方法. 这样您就可以平整DOM结构,并同时在单个注射器元素上配置多个触发器:
<scripts-injector>
<script type="ecopages/injector-map">
{
"on:idle": { "scripts": ["/_assets/tracker.js"] },
"on:interaction": {
"value": "click",
"scripts": ["/_assets/heavy-ui.js"]
}
}
</script>
<!-- Component Content -->
<div class="my-component">...</div>
</scripts-injector>
支持的活动
这个 on:interaction 道克支持广泛的 DOM 事件,定义于 InteractionEvent。 。 。 .
- 鼠标 :
click, (中文(简体) ),dblclick, (中文(简体) ),mousedown, (中文(简体) ),mouseup, (中文(简体) ),mouseenter, (中文(简体) ),mouseleave, (中文(简体) ),mousemove, (中文(简体) ),mouseover, (中文(简体) ),mouseout - 触觉 :
touchstart, (中文(简体) ),touchend, (中文(简体) ),touchmove, (中文(简体) ),touchcancel - 重点:
focus, (中文(简体) ),blur, (中文(简体) ),focusin, (中文(简体) ),focusout - 键盘 :
keydown, (中文(简体) ),keypress, (中文(简体) ),keyup - 表单 :
input, (中文(简体) ),change, (中文(简体) ),submit - 用户:
scroll, (中文(简体) ),resize
数据属性
完成脚本加载后,元素上设置了以下属性:
| 属性 | 说明 |
|---|---|
data-loaded | 装入( 或尝试) 所有脚本时显示 |
data-load-reason | 导致脚本加载的触发器( E)idle, (中文(简体) ), visible, (中文(简体) ), interaction:<event>(中文(简体) ) |
data-error | 以逗号分隔的未加载脚本 URL 列表( 仅在出错时) |
灵感
无可否认,这在很大程度上受到 11t/is-陆地, (中文(简体) ), Astro岛 以及"组件岛"概念,最初由埃特西的前端建筑师凯蒂·赛勒-米勒所引入.