使用 vanilla js 按需加载脚本文件
Load script file on demand with vanilla js
我使用手风琴或乐谱。单击选项卡时,我想显示地图或需要加载大 javascript 文件的内容。
为了不加载不需要的大 javascript,我只想在单击选项卡时加载它。
我该怎么做?我用手风琴和点击事件创建了一个很好的起点。
- 我使用 vanilla js(纯 javascript - 没有 jQuery)
- 我在网页上使用它(不是nodejs)
- 如果它适用于现代浏览器(不需要 IE),我就没问题
window.addEventListener('DOMContentLoaded', () => {
document.querySelector('[data-trigger]').addEventListener('click', () => {
console.log('Load script from file');
// CDN example - https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js
});
});
ul {
list-style: none;
margin: 0;
padding: 0;
}
label {
display: flex;
align-items: center;
}
label:before {
content: '';
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M13.172 12l-4.95-4.95 1.414-1.414L16 12l-6.364 6.364-1.414-1.414z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
width: 24px;
height: 24px;
}
input[type=checkbox] {
display: none;
}
input[type=checkbox]:checked ~ h2 label:before {
transform: rotate(90deg);
}
p {
display: none;
}
input[type=checkbox]:checked ~ h2 ~ p {
display: block;
}
<ul>
<li>
<input type="checkbox" id="faq-1">
<h2 data-trigger>
<label for="faq-1">Click to load map</label>
</h2>
<p>Gummies marzipan croissant chupa chups.</p>
</li>
<li>
<input type="checkbox" id="faq-2">
<h2>
<label for="faq-2">Something else</label>
</h2>
<p>Cookie bear claw carrot cake croissant.</p>
</li>
</ul>
您可以动态创建一个脚本标签,并在按下按钮时将其添加到文档中。这将触发脚本立即加载。使用 onload
回调,您可以 运行 您的代码,例如在脚本实际加载时创建地图。
添加 { once: true }
作为 addEventListener
的第三个参数,因为它将确保触发器只能被单击一次,并且不能多次附加脚本。
function createMap() {
const map = new mapboxgl.Map({
...
});
}
window.addEventListener('DOMContentLoaded', () => {
document.querySelector('[data-trigger]').addEventListener('click', () => {
console.log('Load script from file');
const script = document.createElement('script');
script.id = 'mapboxgljs';
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js'
script.async = true;
script.onload = function() {
console.log('script loaded, you can use it now.');
createMap();
}
document.body.append(script);
}, { once: true }); // Make sure that the button can only be pressed once.
});
由于您习惯只支持现代浏览器,因此可以使用 dynamic import()
函数加载文件:
window.addEventListener('DOMContentLoaded', () => {
document.querySelector('[data-trigger]').addEventListener('click', async() => {
const module = await import('https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js');
console.log(`module is loaded: ${Object.keys(mapboxgl)}`);
});
});
ul {
list-style: none;
margin: 0;
padding: 0;
}
label {
display: flex;
align-items: center;
}
label:before {
content: '';
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M13.172 12l-4.95-4.95 1.414-1.414L16 12l-6.364 6.364-1.414-1.414z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
width: 24px;
height: 24px;
}
input[type=checkbox] {
display: none;
}
input[type=checkbox]:checked~h2 label:before {
transform: rotate(90deg);
}
p {
display: none;
}
input[type=checkbox]:checked~h2~p {
display: block;
}
<ul>
<li>
<input type="checkbox" id="faq-1">
<h2 data-trigger>
<label for="faq-1">Click to load map</label>
</h2>
<p>Gummies marzipan croissant chupa chups.</p>
</li>
<li>
<input type="checkbox" id="faq-2">
<h2>
<label for="faq-2">Something else</label>
</h2>
<p>Cookie bear claw carrot cake croissant.</p>
</li>
</ul>
import()
returns 一个在成功获取时解析的承诺,并在后续调用(在我的测试中)中立即解析,因此您不必专门处理它。
对于您的特定 mapbox-gl
脚本,返回的值将没有用,因为脚本不是作为 ES6 模块编写的,而是脚本的 side-effects 运行 将就位(在这种情况下,mapboxgl
变量被分配给 globalThis
)。在加载脚本为模块的场景下(正确使用export
),可以直接使用解析后的值,避免污染全局命名空间
我使用手风琴或乐谱。单击选项卡时,我想显示地图或需要加载大 javascript 文件的内容。
为了不加载不需要的大 javascript,我只想在单击选项卡时加载它。
我该怎么做?我用手风琴和点击事件创建了一个很好的起点。
- 我使用 vanilla js(纯 javascript - 没有 jQuery)
- 我在网页上使用它(不是nodejs)
- 如果它适用于现代浏览器(不需要 IE),我就没问题
window.addEventListener('DOMContentLoaded', () => {
document.querySelector('[data-trigger]').addEventListener('click', () => {
console.log('Load script from file');
// CDN example - https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js
});
});
ul {
list-style: none;
margin: 0;
padding: 0;
}
label {
display: flex;
align-items: center;
}
label:before {
content: '';
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M13.172 12l-4.95-4.95 1.414-1.414L16 12l-6.364 6.364-1.414-1.414z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
width: 24px;
height: 24px;
}
input[type=checkbox] {
display: none;
}
input[type=checkbox]:checked ~ h2 label:before {
transform: rotate(90deg);
}
p {
display: none;
}
input[type=checkbox]:checked ~ h2 ~ p {
display: block;
}
<ul>
<li>
<input type="checkbox" id="faq-1">
<h2 data-trigger>
<label for="faq-1">Click to load map</label>
</h2>
<p>Gummies marzipan croissant chupa chups.</p>
</li>
<li>
<input type="checkbox" id="faq-2">
<h2>
<label for="faq-2">Something else</label>
</h2>
<p>Cookie bear claw carrot cake croissant.</p>
</li>
</ul>
您可以动态创建一个脚本标签,并在按下按钮时将其添加到文档中。这将触发脚本立即加载。使用 onload
回调,您可以 运行 您的代码,例如在脚本实际加载时创建地图。
添加 { once: true }
作为 addEventListener
的第三个参数,因为它将确保触发器只能被单击一次,并且不能多次附加脚本。
function createMap() {
const map = new mapboxgl.Map({
...
});
}
window.addEventListener('DOMContentLoaded', () => {
document.querySelector('[data-trigger]').addEventListener('click', () => {
console.log('Load script from file');
const script = document.createElement('script');
script.id = 'mapboxgljs';
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js'
script.async = true;
script.onload = function() {
console.log('script loaded, you can use it now.');
createMap();
}
document.body.append(script);
}, { once: true }); // Make sure that the button can only be pressed once.
});
由于您习惯只支持现代浏览器,因此可以使用 dynamic import()
函数加载文件:
window.addEventListener('DOMContentLoaded', () => {
document.querySelector('[data-trigger]').addEventListener('click', async() => {
const module = await import('https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.12.0/mapbox-gl.js');
console.log(`module is loaded: ${Object.keys(mapboxgl)}`);
});
});
ul {
list-style: none;
margin: 0;
padding: 0;
}
label {
display: flex;
align-items: center;
}
label:before {
content: '';
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M13.172 12l-4.95-4.95 1.414-1.414L16 12l-6.364 6.364-1.414-1.414z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
width: 24px;
height: 24px;
}
input[type=checkbox] {
display: none;
}
input[type=checkbox]:checked~h2 label:before {
transform: rotate(90deg);
}
p {
display: none;
}
input[type=checkbox]:checked~h2~p {
display: block;
}
<ul>
<li>
<input type="checkbox" id="faq-1">
<h2 data-trigger>
<label for="faq-1">Click to load map</label>
</h2>
<p>Gummies marzipan croissant chupa chups.</p>
</li>
<li>
<input type="checkbox" id="faq-2">
<h2>
<label for="faq-2">Something else</label>
</h2>
<p>Cookie bear claw carrot cake croissant.</p>
</li>
</ul>
import()
returns 一个在成功获取时解析的承诺,并在后续调用(在我的测试中)中立即解析,因此您不必专门处理它。
对于您的特定 mapbox-gl
脚本,返回的值将没有用,因为脚本不是作为 ES6 模块编写的,而是脚本的 side-effects 运行 将就位(在这种情况下,mapboxgl
变量被分配给 globalThis
)。在加载脚本为模块的场景下(正确使用export
),可以直接使用解析后的值,避免污染全局命名空间