海轮 發表於 2025-10-11 11:11:00

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">&lt;script&gt;
const name = '公众号:前端路引'
console.log(name)
&lt;/script&gt;
</code></pre>
<h3 id="2引入外部脚本">2、引入外部脚本</h3>
<p>使用 <code>src</code> 属性直接引入外部脚本,这是目前大部分前端项目的用法,虽然 <code>vite</code> 直接使用 ES 模块化打包,但要兼容低版本浏览器还是得转成普通的 js 文件引入:</p>
<pre><code class="language-html">&lt;script src="project/path/script.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="3defer-延迟">3、defer 延迟</h3>
<p>标签的 <code>defer</code> 属性可以控制脚本异步加载,并且能让脚本顺序执行:</p>
<pre><code class="language-html">&lt;script defer src="project/path/script1.js"&gt;&lt;/script&gt;
&lt;script defer src="project/path/script2.js"&gt;&lt;/script&gt;
</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">&lt;script async src="project/path/script1.js"&gt;&lt;/script&gt;
&lt;script async src="project/path/script2.js"&gt;&lt;/script&gt;
</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">&lt;script src="https://cdn.xxx.com/jquery.js" integrity="sha384-..."&gt;
&lt;/script&gt;
</code></pre>
<h3 id="7跨域控制">7、跨域控制</h3>
<p><code>crossorigin</code> 属性用于控制跨域请求的凭据传递:</p>
<pre><code class="language-html">&lt;script src="https://other-domain.com/script.js" crossorigin="anonymous"&gt;&lt;/script&gt;
</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">&lt;script type="module" src="main.mjs"&gt;&lt;/script&gt;
&lt;script type="module"&gt;
import { foo } from './foo.js';
&lt;/script&gt;
</code></pre>
<h3 id="9nomodule-兼容">9、nomodule 兼容</h3>
<p><code>nomodule</code> 属性,用于兼容不支持 ES 模块的浏览器,如果浏览器不支持 ES 模块,则 <code>nomodule</code> 属性下的脚本会被执行,反之则不会执行。</p>
<pre><code class="language-html">&lt;script nomodule src="project/path/fallback.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="10动态导入">10、动态导入</h3>
<p>ES 模块允许在代码执行时导入模块,此方式就称之为 <code>动态导入</code>:</p>
<pre><code class="language-html">&lt;script type="module"&gt;
const isMobile = navigator.userAgent.match(/mobile/i);
if (isMobile) {
    import('./project/path/mobile.js').then(module =&gt; {
      module.default();
    })
}
&lt;/script&gt;
</code></pre>
<h3 id="11模块映射">11、模块映射</h3>
<p><code>type="importmap"</code> 属性允许指定 ES 模块的映射关系,在后续书写时候就不必再写完整的模块路径,可以只写模块名:</p>
<pre><code class="language-html">&lt;script type="importmap"&gt;
{
"imports": {
    "lodash": "https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm"
}
}
&lt;/script&gt;
&lt;script type="module"&gt;
import _ from "lodash"; // 实际加载 CDN 资源
_.chunk(, 2);
&lt;/script&gt;
</code></pre>
<h3 id="12模版字符串">12、模版字符串</h3>
<p>利用自定义的 <code>type</code> 属性,可以将一些 HTML 字符串写在 script 标签中,比如 vue 的模版字符串:</p>
<pre><code class="language-html">&lt;script type="text/x-template" id="index"&gt;
&lt;div class="index"&gt;
    &lt;h3&gt;点击历史记录跳转会保存滚动条位置&lt;/h3&gt;
    &lt;p v-for="(item,index) in list" :key="index"&gt;
      &lt;template v-if="index % 8 !== 0"&gt;
      {{ index }}
      &lt;/template&gt;
      &lt;template v-else&gt;
      &lt;p&gt;&lt;a href="javascript:;" @click="$router.go(1)"&gt;历史记录前往下一页&lt;/a&gt;&lt;/p&gt;
      &lt;router-link :to="{ name: 'details' }"&gt;跳转前往详情页&lt;/router-link&gt;
      &lt;/template&gt;
    &lt;/p&gt;
&lt;/div&gt;
&lt;/script&gt;
&lt;script&gt;
var list = (new Array(50)).fill('1')
Vue.component('Index', {
    template: '#index',
    data: function () {
      return {
      list: list
      }
    },
})
&lt;/script&gt;
</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>&nbsp;</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>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/linx/p/19134600
頁: [1]
查看完整版本: Web前端入门第 88 问:引入 JavaScript 的 script 标签究竟有多少用法?