【JavaScript】script 标签的使用

script 标签

script 标签之间共享顶层对象。

<script>var a = 1;
</script><script>console.log(a); // 1
</script>

但是全局变量作用域的提升机制在这些边界中不适用:

<script>foo();
</script><script>function foo() {console.log('foo');}
</script>

但是下面的两段代码则没问题:

<script>foo();function foo() {console.log('foo');}
</script>
<script>function foo() {console.log('foo');}
</script><script>foo();
</script>

如果 script 中的代码(无论是内联代码还是外部代码)发生错误,它会像独立的 JS 程序那样停止,但是后续的 script 中的代码依然会接着运行,不会受影响。


内联代码和外部文件中的代码之间有一个区别,即在内联代码中不可以出现 </script> 字符串,一旦出现即被视为代码块结束。因此对于下面这样的代码需要非常小心:

<script>var code = "<script>alert('Hello World')</script>";
</script>

上述代码看似没什么问题,但是字符串常量中的 </script> 将会被当作结束标签来处理,因此会导致错误。

常用的变通方法是:

'</' + 'script>';

使用转义字符 \ 也可:

<script>function sayScript() {console.log('<\/script>'); // 使用转义字符}
</script>

另外需要注意的一点是,我们是根据代码文件的字符集属性来解析外部文件中的代码,而内联代码则使用其所在页面文件的字符集。

内联代码的 script 标签没有 charset 属性。



script 标签的属性

  1. src:可选。指定外部脚本文件。
  2. async:可选。表示异步加载脚本,加载完成后立即执行。只对外部脚本文件有效。
  3. defer:可选。表示异步加载脚本,等到文档完全被解析和显示之后再执行。只对外部脚本文件有效。
  4. crossorigin:可选。配置相关请求的 CORS(跨源资源共享)设置。默认不使用 CORS。crossorigin="anonymous" 表示文件请求不会设置凭据标志。crossorigin="use-credentials" 表示文件请求会设置凭据标志,意味着出站请求会包含凭据。
  5. integrity:可选。允许比对接收到的资源和指定的加密签名以验证子资源完整性(SRI,Subresource Integrity)。如果接收到的资源的签名与这个属性指定的签名不匹配,则页面会报错,脚本不会执行。这个属性可以用于确保内容分发网络(CDN, Content Delivery Network)不会提供恶意内容。



script 标签的使用

使用了 src 属性的 <script> 元素不应该再在 <script></script> 标签中包含其他 JS 代码。如果两者都提供的话,则浏览器只会下载并执行外部脚本文件,从而忽略行内代码。


<img> 元素很像,<script> 元素的 src 属性可以是一个完整的 URL,而且这个 URL 指向的资源可以跟包含它的 HTML 页面不在同一个域中。

浏览器在解析这个资源时,会向 src 属性指定的路径发送一个 GET 请求,以取得相应资源,假定是一个 JS 文件。这个初始的请求不受浏览器同源策略限制,但返回并被执行的 JS 则受限制。当然,这个请求仍然受父页面 HTTP/HTTPS 协议的限制。

来自外部域的代码会被当成加载它的页面的一部分来加载和解释。这个能力可以让我们通过不同的域分发 JS。不过,引用了放在别人服务器上的 JS 文件时要格外小心,因为恶意的程序员随时可能替换这个文件。在包含外部域的 JS 文件时,要确保该域是自己所有的,或者该域是一个可信的来源。<script> 标签的 integrity 属性是防范这种问题的一个武器。


不管包含的是什么代码,浏览器都会按照 <script> 在页面中出现的顺序依次解释它们,前提是它们没有使用 deferasync 属性。第二个 <script> 元素的代码必须在第一个 <script> 元素的代码解释完毕才能开始解释,第三个则必须等第二个解释完,以此类推。



script 标签位置

script 标签会阻塞 HTML 的解析,所以尽量放在 HTML 的底部,以免影响页面的首屏渲染。

当浏览器遇到 script 标签时,它会暂停解析 HTML 文档,先去执行 script 标签中的 JS 代码,因为 JS 代码可能会修改 HTML 的结构或内容。这样就会导致页面的渲染被延迟,用户看到的是一个空白的页面,直到 script 标签执行完毕,浏览器才会继续解析 HTML 文档,并渲染页面。所以,为了提高用户体验,我们应该尽量把 script 标签放在 HTML 的底部,这样就可以让浏览器先解析和渲染页面的首屏内容,再去执行 script 标签中的 JS 代码。

假设我们有一个内联的 JS 代码,它会在页面加载时执行一些耗时的逻辑,我们把它放在 head 标签内,比如:

<html><head><!-- 内联 JS 放在 head 标签内, 会阻塞 HTML 的解析和页面的渲染 --><script>// 一些耗时的逻辑for (var i = 0; i < 1000000000; i++) {}</script></head><body><!-- 页面内容 --><h1>Hello World</h1></body>
</html>

这样的话,用户打开这个页面时,会看到一个空白的页面,直到内联 JS 执行完毕,才会看到 “Hello World”。

如果我们把内联 JS 放在 body 标签的底部,比如:

<html><head> </head><body><!-- 页面内容 --><h1>Hello World</h1><!-- 内联 JS 放在 body 标签的底部, 不会阻塞 HTML 的解析和页面的渲染 --><script>// 一些耗时的逻辑for (var i = 0; i < 1000000000; i++) {}</script></body>
</html>

这样的话,用户打开这个页面时,会先看到 “Hello World”,然后再等待内联 JS 执行完毕。这样就可以提高用户体验。



推迟执行脚本

<script> 元素上设置 defer 属性,相当于告诉浏览器立即下载,但延迟执行defer 属性表示脚本会被延迟到整个页面都解析完毕后再运行。

<!DOCTYPE html>
<html><head><title>Example HTML Page</title><script defer src="example1.js"></script><script defer src="example2.js"></script></head><body><!-- 这里是页面内容 --></body>
</html>

虽然这个例子中的 <script> 元素包含在页面的 <head> 中,但它们会在浏览器解析到结束的 </html> 标签后才会执行。HTML5 规范要求脚本应该按照它们出现的顺序执行,因此第一个推迟的脚本会在第二个推迟的脚本之前执行,而且两者都会在 DOMContentLoaded 事件之前执行。不过在实际当中,推迟执行的脚本不一定总会按顺序执行或者在 DOMContentLoaded 事件之前执行,因此最好只包含一个这样的脚本。

如前所述,defer 属性只对外部脚本文件才有效。



异步执行脚本

<script> 元素上设置 async 属性,会告诉浏览器立即开始下载。不过,与 defer 不同的是,标记为 async 的脚本并不保证能按照它们出现的次序执行,比如:

<!DOCTYPE html>
<html><head><title>Example HTML Page</title><script async src="example1.js"></script><script async src="example2.js"></script></head><body><!-- 这里是页面内容 --></body>
</html>

在这个例子中,第二个脚本可能先于第一个脚本执行。因此,重点在于它们之间没有依赖关系。给脚本添加 async 属性的目的是告诉浏览器,不必等脚本下载和执行完后再加载页面,同样也不必等到该异步脚本下载和执行后再加载其他脚本。正因为如此,异步脚本不应该在加载期间修改 DOM。

异步脚本保证会在页面的 load 事件前执行,但可能会在 DOMContentLoaded 之前或之后。



动态加载脚本

const script = document.createElement('script');
script.src = 'gibberish.js';
document.head.appendChild(script);

在把 HTMLElement 元素添加到 DOM 且执行到这段代码之前不会发送请求。

默认情况下,动态创建的 <script> 元素是以异步方式加载的,相当于添加了 async 属性。如果要统一动态脚本的加载行为,可以明确将其设置为同步加载:

const script = document.createElement('script');
script.src = 'gibberish.js';
script.async = false;
document.head.appendChild(script);

以这种方式获取的资源对浏览器预加载器是不可见的。这会严重影响它们在资源获取队列中的优先级。根据应用程序的工作方式以及怎么使用,这种方式可能会严重影响性能。要想让预加载器知道这些动态请求文件的存在,可以在文档头部显式声明它们:

<link rel="preload" href="gibberish.js" />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/176148.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浪潮信息inMerge超融合 刷新全球vSAN架构虚拟化VMmark最佳成绩

近日&#xff0c;在国际权威的VMmark测试中&#xff0c;浪潮信息inMerge1100超融合产品搭载NF5280M7服务器&#xff0c;满载运行44Tiles取得40.95分的成绩&#xff0c;刷新了vSAN架构&#xff08;Intel双路最新平台&#xff09;虚拟化性能测试纪录。该测试结果证明inMerge1100可…

hdlbits系列verilog解答(移位寄存器)-23

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 您将获得一个具有两个输入和一个输出的模块 my_dff &#xff08;实现 D 触发器&#xff09;。实例化其中的三个&#xff0c;然后将它们链接在一起以形成长度为 3 的移位寄存器。端口 clk 需要连接到所有实例。…

linux查看系统版本、内核信息、操作系统类型版本

1. 使用 uname 命令&#xff1a;这将显示完整的内核版本信息&#xff0c;包括内核版本号、主机名、操作系统类型等。 uname -a2. 使用 lsb_release 命令&#xff08;仅适用于支持 LSB&#xff08;Linux Standard Base&#xff09;的发行版&#xff09;&#xff1a;这将显示包含…

如何优雅地单元测试 Kotlin/Java 中的 private 方法?

翻译自 https://medium.com/mindorks/how-to-unit-test-private-methods-in-java-and-kotlin-d3cae49dccd ❓如何单元测试 Kotlin/Java 中的 private 方法❓ 首先&#xff0c;开发者应该测试代码里的 private 私有方法吗&#xff1f; 直接信任这些私有方法&#xff0c;测试到…

Servlet 上下文参数

7)Servlet上下文对象&#xff1a;ServletContext生活中的例子&#xff1a;张三和李四在不远处窃窃私语&#xff0c;并且频繁的对着你坏笑。你肯定会跑过去问&#xff1a;你们俩在聊什么&#xff1f;注意&#xff1a;此处的聊什么&#xff0c;其实就是你在咨询他们聊天的上下文&…

FreeRTOS深入教程(队列内部机制和源码分析)

文章目录 前言一、队列结构体分析二、创建队列三、读写队列源码分析1.读队列源码分析2.写队列源码分析 总结 前言 本篇文章主要来为大家分析队列的内部机制和源码实现。 一、队列结构体分析 在FreeRTOS中队列会使用一个结构体来表示&#xff1a; 1.int8_t * pcHead 和 int…

V90PN总线伺服梯形加减速速度控制(标准报文1应用)

V90 PN总线伺服速度控制应用可以利用标准报文1和SinaSpeed功能块实现,具体代码介绍请查看下面相关文章链接,这里不再赘述。 速度随动控制 V90伺服PN总线速度随动控制(手摇轮功能)-CSDN博客文章浏览阅读40次。V90PN总线控制相关内容,请参考下面文章链接:博途1200/1500PLC …

使用tensorflow创建自己的量化金融工具

介绍 在充满活力的金融领域,高频交易 (HFT) 已经成为游戏规则的改变者。高频交易能够在几毫秒内执行数千个订单,利用先进的算法和计算技术实时利用微小的价格差异。随着金融市场的不断发展,支持高频交易策略的工具和框架也必须不断发展。在这一背景下,TF Quant Finance (T…

物联网AI MicroPython传感器学习 之 SHT3X温湿度传感器

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 Sensirion SHT3x-DIS湿度和温度传感器基于CMOSens传感器芯片&#xff0c;更加智能、可靠&#xff0c;精度更高。SHT3x-DIS具有增强的信号处理能力、两个独特的用户可选I2C地址&#xff0c;通信…

JavaScript基础知识19——循环结构:while循环

哈喽&#xff0c;你好&#xff0c;我是雷工。 本节学习JavaScript基础语法的循环结构&#xff1a;while循环&#xff0c;以下为学习笔记。 while循环 循环概念&#xff1a;重复执行一些操作&#xff1b; 循环特征&#xff1a;不断地重复&#xff1b; while&#xff1a;在…期间…

监控浏览器页面展示性能的工具

B/S架构&#xff0c;用户都是使用浏览器访问后端服务&#xff0c;产品在开发时需要关注用户的体验&#xff0c;不仅包含交互的友好&#xff0c;性能指标也非常重要。对于后端开发常见的性能指标&#xff0c;可能包含&#xff1a;reponse time&#xff0c;吞吐量等。此外&#x…

【数据结构】顺序表

今天给大家带来的是顺序表相关知识的分享&#xff0c;喜欢的朋友可以三连一波&#xff01;&#xff01;&#xff01; 顺序表 顺序表的基本结构&#xff1a; 顺序表的实现 我们将顺序表的实现分装成函数大概分为下面几类&#xff1a; //初始化 void InitSL(SL* psl); //打印数…

最新waymo数据集 百度网盘

最新waymo数据集介绍 waymo数据集是有史以来最大&#xff0c;最多样化的自动驾驶数据集&#xff0c;包含 传感器数据边界框数据2D视频全景分割标签关键点标签3D语义分割标签2D和3D边界框的关联 是该领域质量最高、规模最大的数据集之一&#xff0c;用于帮助研究界在机器感知…

管理类联考——英语二——阅读篇——题材:心理

文章目录 2013年&#xff0c;Text 3——题材&#xff1a;心理细节题&#xff08;难&#xff09;细节题——排除法细节题细节题观点态度题 2015 年&#xff0c;Text 1——题材&#xff1a;心理细节题细节题推断题词义句意题细节题 2019 年&#xff0c;Text 1——题材&#xff1a…

c语言练习(9周)

输入样例11输出样例7.0980 #include<stdio.h> int main() {int n, i;double s 1,a1;scanf("%d", &n);for (i 2; i < n; i) {a 1 / (1a);s a;}printf("%.4lf", s);return 0; } 题干输入10个整数&#xff0c;分别按输入正序、逆序显示。输…

TSINGSEE青犀AI视频识别技术+危化安全生产智慧监管方案

一、背景分析 石油与化学工业生产过程复杂多样&#xff0c;涉及的物料易燃易爆、有毒有害&#xff0c;生产条件多高温高压、低温负压&#xff0c;现场危险化学品存储量大、危险源集中&#xff0c;重特大安全事故多发。打造基于工业互联网的安全生产新型能力&#xff0c;提高危…

SaaS 出海,如何搭建国际化服务体系?(一)

防噎指南&#xff1a;这可能是你看到的干货含量最高的 SaaS 出海经验分享&#xff0c;请准备好水杯&#xff0c;放肆食用&#xff08;XD。 当越来越多中国 SaaS 企业选择开启「国际化」副本&#xff0c;出海便俨然成为国内 SaaS 的新角斗场。 LigaAI 观察到&#xff0c;出海浪…

【Python 常用脚本及命令系列 9 -- 图片文字识别 EasyOCR使用】

文章目录 1.1 EasyOCR 介绍1.1.1 EasyOCR 安装1.1.2 EasyOCR 使用方法1.1.2.1 EasyOCR 支持的语言种类1.1.2.2 EasyOCR 支持的图像格式 EasyOCR 提高图片文字识别正确率1.3 问题总结 1.1 EasyOCR 介绍 Python中有一个不错的OCR库-EasyOCR&#xff0c;在GitHub已有9700 star。它…

Stable Diffusion系列(一):古早显卡上最新版 WebUI 安装及简单操作

文章目录 Stable Diffusion安装AnimateDiff插件适配sdxl模型适配 Stable Diffusion使用插件安装界面设置基础文生图加入lora的文生图 Stable Diffusion安装 我的情况比较特殊&#xff0c;显卡版本太老&#xff0c;最高也就支持cuda10.2&#xff0c;因此只能安装pytorch1.12.1&…

十八、模型构建器(ModelBuilder)快速提取城市建成区——批量掩膜提取夜光数据、夜光数据转面、面数据融合、要素转Excel(基于参考比较法)

一、前言 前文实现批量投影栅格、转为整型,接下来重点实现批量提取夜光数据,夜光数据转面、夜光数据面数据融合、要素转Excel。将相关结果转为Excel,接下来就是在Excel中进行阈值的确定,阈值确定无法通过批量操作,除非采用其他方式,但是那样的学习成本较高,对于参考比较…