昨天写一个demo测试某个库,看了库的介绍,有node版本和ES6版本,心血来潮干脆用原生html写测试demo了。 使用
<script type="module"></script>这种模块的方式,可以导入ES6模块。
<body>
<button id="del-btn">删除 </button><br><br>
<script type="module">
import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
document.querySelector('#del-btn').addEventListener('click', handleDeleteRepo, false);
function handleDeleteRepo(){
// ...
}
</script>
</body>
</html>
坑点:
- 不要在
<button id="del-btn">删除 </button>按钮上绑定onclick事件,如:onclick=“handleDeleteRepo”, 事件代码不会被执行。 - 这是因为type=module内的代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。说白了就是按钮上的handleDeleteRepo事件是无法被访问的。
- 解决方案: 在模块内的js中,添加事件监听事件,如
document.querySelector('#del-btn').addEventListener('click', handleDeleteRepo, false);
知识点:
-
浏览器加载 ES6 模块,使用
<script type="module"> // your code ... </script> // 或者 <script type="module" src="./jquery.js"></script> -
浏览器对于带有
type="module"的<script>,都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,等同于打开了<script>标签的defer属性。 -
module 内的代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。
-
同一个模块如果加载多次,将只执行一次。
-
模块之中,顶层的
this关键字返回undefined,而不是指向window。 -
defer与async属性的区别是:defer要等到整个页面渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;async一旦js下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。- 一句话,
defer是“页面渲染完再执行”,async是“js下载完就执行”。 - 另外,如果有多个
defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。