Web前端入门第 88 问:引入 JavaScript 的 script 标签究竟有多少用法?
<p>HTML 版本不停的更新迭代,也导致浏览器支持的写法眼花缭乱,就拿 script 标签来说,刚刚入行的那会儿就只知道用来写内联的 js 代码,后来又学到了引入 js 文件,ES 模块规范化之后又知道能用来引入模块化的 js 代码,可这就是它的全部了吗??</p><p>然而...并不是!!!</p>
<h2 id="各种用法">各种用法</h2>
<p>看看 script 千奇百怪的用法,一定有你没见过的~~</p>
<h3 id="1内联脚本">1、内联脚本</h3>
<p>如文章开头说的一样,直接用来写内联脚本,本公众号大部分文章都是使用内联脚本的方式所写:</p>
<pre><code class="language-html"><script>
const name = '公众号:前端路引'
console.log(name)
</script>
</code></pre>
<h3 id="2引入外部脚本">2、引入外部脚本</h3>
<p>使用 <code>src</code> 属性直接引入外部脚本,这是目前大部分前端项目的用法,虽然 <code>vite</code> 直接使用 ES 模块化打包,但要兼容低版本浏览器还是得转成普通的 js 文件引入:</p>
<pre><code class="language-html"><script src="project/path/script.js"></script>
</code></pre>
<h3 id="3defer-延迟">3、defer 延迟</h3>
<p>标签的 <code>defer</code> 属性可以控制脚本异步加载,并且能让脚本顺序执行:</p>
<pre><code class="language-html"><script defer src="project/path/script1.js"></script>
<script defer src="project/path/script2.js"></script>
</code></pre>
<p>以上脚本就算写在 head 标签中,也不会阻止 dom 解析,而且 <code>script2.js</code> 一定是在 <code>script1.js</code> 之后执行。</p>
<h3 id="4async-异步">4、async 异步</h3>
<p><code>async</code> 也能控制脚本异步加载,但不同的是 <code>async</code> 加载的脚本无法保证脚本执行顺序。</p>
<pre><code class="language-html"><script async src="project/path/script1.js"></script>
<script async src="project/path/script2.js"></script>
</code></pre>
<p>以上脚本没办法保证 <code>script1.js</code> 一定会先执行!!!此属性一般多用于加载与项目流程无关的一些 js 文件,比如说:统计代码、广告代码等等。</p>
<h3 id="5动态加载脚本">5、动态加载脚本</h3>
<p>使用 js 创建 script 标签引入 js 文件,即可实现 js 脚本的动态加载:</p>
<pre><code class="language-js">const script = document.createElement('script');
script.src = 'dynamic.js';
script.onload = function () {
console.log('dynamic.js 加载成功!');
}
script.onerror = function () {
console.log('dynamic.js 加载失败!');
}
// 脚本插入到页面中才会开始加载
document.head.appendChild(script);
</code></pre>
<h3 id="6资源完整性校验">6、资源完整性校验</h3>
<p><code>integrity</code> 属性能用于校验资源是否被篡改,详细算法参考:https://developer.mozilla.org/zh-CN/docs/Web/Security/Subresource_Integrity</p>
<pre><code class="language-html"><script src="https://cdn.xxx.com/jquery.js" integrity="sha384-...">
</script>
</code></pre>
<h3 id="7跨域控制">7、跨域控制</h3>
<p><code>crossorigin</code> 属性用于控制跨域请求的凭据传递:</p>
<pre><code class="language-html"><script src="https://other-domain.com/script.js" crossorigin="anonymous"></script>
</code></pre>
<ul>
<li>anonymous:不发送凭据(如 Cookies)</li>
<li>use-credentials:发送凭据</li>
</ul>
<h3 id="8es-模块">8、ES 模块</h3>
<p>使用 <code>type="module"</code> 即可在 script 标签内使用 ES 模块语法,这与浏览器的版本有关,一些低版本可能并不支持!!</p>
<pre><code class="language-html"><script type="module" src="main.mjs"></script>
<script type="module">
import { foo } from './foo.js';
</script>
</code></pre>
<h3 id="9nomodule-兼容">9、nomodule 兼容</h3>
<p><code>nomodule</code> 属性,用于兼容不支持 ES 模块的浏览器,如果浏览器不支持 ES 模块,则 <code>nomodule</code> 属性下的脚本会被执行,反之则不会执行。</p>
<pre><code class="language-html"><script nomodule src="project/path/fallback.js"></script>
</code></pre>
<h3 id="10动态导入">10、动态导入</h3>
<p>ES 模块允许在代码执行时导入模块,此方式就称之为 <code>动态导入</code>:</p>
<pre><code class="language-html"><script type="module">
const isMobile = navigator.userAgent.match(/mobile/i);
if (isMobile) {
import('./project/path/mobile.js').then(module => {
module.default();
})
}
</script>
</code></pre>
<h3 id="11模块映射">11、模块映射</h3>
<p><code>type="importmap"</code> 属性允许指定 ES 模块的映射关系,在后续书写时候就不必再写完整的模块路径,可以只写模块名:</p>
<pre><code class="language-html"><script type="importmap">
{
"imports": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm"
}
}
</script>
<script type="module">
import _ from "lodash"; // 实际加载 CDN 资源
_.chunk(, 2);
</script>
</code></pre>
<h3 id="12模版字符串">12、模版字符串</h3>
<p>利用自定义的 <code>type</code> 属性,可以将一些 HTML 字符串写在 script 标签中,比如 vue 的模版字符串:</p>
<pre><code class="language-html"><script type="text/x-template" id="index">
<div class="index">
<h3>点击历史记录跳转会保存滚动条位置</h3>
<p v-for="(item,index) in list" :key="index">
<template v-if="index % 8 !== 0">
{{ index }}
</template>
<template v-else>
<p><a href="javascript:;" @click="$router.go(1)">历史记录前往下一页</a></p>
<router-link :to="{ name: 'details' }">跳转前往详情页</router-link>
</template>
</p>
</div>
</script>
<script>
var list = (new Array(50)).fill('1')
Vue.component('Index', {
template: '#index',
data: function () {
return {
list: list
}
},
})
</script>
</code></pre>
<h2 id="实验性属性">实验性属性</h2>
<ul>
<li><strong>fetchpriority:</strong>允许指定外部脚本的加载优先级。有效值:<code>high</code>/<code>low</code>/<code>auto</code></li>
<li><strong>blocking:</strong>可以指定在脚本加载时,浏览器中的页面渲染应该被阻断。有效值:<code>render</code></li>
</ul>
<h2 id="写在最后">写在最后</h2>
<p>强大的 <code>script</code> 标签早就不止用于写 js 代码了,各种用法真是让人眼花缭乱,一不小心就踩到没见过的用法~~</p>
<blockquote>
<p>参考资料:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Elements/script</p>
</blockquote>
</div>
<div id="MySignature" role="contentinfo">
<p> </p>
<p style="font-size: 18px;font-weight: bold;">文章首发于微信公众号【<span style="color:rgb(255, 71, 87)">前端路引</span>】,欢迎 <span style="color:#4ec259">微信扫一扫</span> 查看更多文章。</p>
<p>
<img style="max-width: 320px;" src="https://images.cnblogs.com/cnblogs_com/linx/2447020/o_250228035031_%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.png"/>
</p>
<p>本文来自博客园,作者:前端路引,转载请注明原文链接:https://www.cnblogs.com/linx/p/19134600</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/linx/p/19134600
頁:
[1]