Script 标签-----JavaScript整理、复习、梳理、面试题

JavaScript

笔者突然想把所学的JS梳理整理一边,一方面完善自己的不足,另一方面也希望看到这篇文章的人能指出笔者的不足,在此谢过了。(根据红宝书结合自己的想法整理出来,同时也会加上一些相关的面试题)

HTML里的JS

1. <script>标签

javascript插入html中主要使用的是script这个标签这个标签有8个属性

async:可选属性。表示可以立刻开始下载脚本,但不能阻止其他页面动作。只对外部文件有效
charset:可选属性。使用src指定代码字符集。
crossorigin:可选属性。配置相关请求的CROS设置。
defer:可选属性。表示在文档解析和显示完成后在执行脚本是没有问题的。只对外部脚本文件有效
integrity:可选属性。允许比对接收到的资源和指定的加密签名以验证子资源完整性
src:可选属性。表示要执行的外部文件
type:可选属性。代替language表示代码块中脚本语言的内容类型(也称MIME类型)。
language:已废弃

src

script标签如果使用了src属性就不能在标签中使用代码,若两者都提供的话,就只会下载脚本而忽略标签中的代码。同时script的src属性可以是一个完整的url,而且这个url指向的资源可以跟包含他的HTML不是同一个域

<script src="https://www.somewhere.com/afile.js"></script>

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

defer

推迟执行脚本:script元素添加defer属性后,不会改变页面的结构,所以这个脚本可以在整个页面解析完后在执行。设置这个属性会告诉浏览器立即下载脚本,但是最后执行脚本同时多个设置了defer属性的script元素,按照HTML5规范的要求应该按照顺序执行。
因为不是所有的浏览器都支持defer属性所以,最好把推迟执行的脚本放在页面的底部。
值得注意的是对于XHTML文档指定defer属性时应该写成defer="defer"

async(不推荐使用这个方法)

异步执行脚本:从改变脚本执行方式上来看async与defer类似。两个属性都只适用于外部脚本文件,都会告诉浏览器立刻开始下载文件,但是使用async的脚本文件不一定会按照顺序执行,所以使用async的脚本之间不能存在依赖关系,给脚本添加async属性的目的就是告诉浏览器,不用等到脚本下载和执行完后在加载页面,同时也不用等到异步脚本下载和执行后再加载其他脚本,所以异步脚本不应该在加载期间修改DOM元素
值得注意的是对于XHTML文档指定defer属性时应该写成async="async"

动态加载脚本

因为JavaScript可以使用DOM的API所以通过向DOM中添加script元素同样可以加载指定脚本。只要创建script元素并添加到DOM中就行

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

这样添加到DOM元素后,执行这段代码之前是不会发送请求的。因为默认情况向相当于script元素添加了async属性,但是所有的浏览器都支持createElement()方法,但不是所有的浏览器都支持async,所以要统一动态脚本的加载行为,可以将其设置成同步加载:

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

但是这种方式也是有缺陷的,因为这种方式获取的资源对浏览器预加载器是不可见的,这会严重影响他们在资源获取队列中的优先级。所以要让预加载器知道这些请求文件可以在文档头部显示声明:

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

2. <noscript>标签

针对早期浏览器不支持JavaScript的问题,需要一个优雅降级的处理方案,所以noscript出现用以对不支持JavaScript提供替代内容。对于禁用JavaScript的浏览器有自己的用处。
noscript元素可以包含任何可以出现在body中的HTML元素,script除外。在下列两种情况下,浏览器将显示包含在noscript中的内容

扫描二维码关注公众号,回复: 17176230 查看本文章
  1. 浏览器不支持脚本
  2. 浏览器对脚本的支持关闭

3. 面试题

简述一下srchref的区别
  1. src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。
  2. srcsource的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素
  3. hrefHypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,

如果我们在文档中添加<link href="common.css" rel="stylesheet"/>那么浏览器会识别该文档为css文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用link方式来加载css,而不是使用@import方式

<script src ="js.js"></script> 当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部

script 的位置是否会影响首屏显示时间
  1. 在解析 HTML 生成 DOM 过程中,js 文件的下载是并行的,不需要 DOM 处理到 script 节点。因此,script的位置不影响首屏显示的开始时间。
  2. 浏览器解析 HTML 是自上而下的线性过程,script作为 HTML 的一部分同样遵循这个原则。因此,script 会延迟 DomContentLoad,只显示其上部分首屏内容,从而影响首屏显示的完成时间
script标签的deferasync有什么区别
  1. script:HTML暂停解析,下载JS,执行JS,在继续解析HTML。
  2. defer:HTML继续解析,并行下载JSHTML解析完在执行JS(不用把script放到body后面,我们在head中<script defer>让js脚本并行加载会好点)
  3. async:HTML继续解析,并行下载JS,执行JS(加载完毕后立即执行,谁先加载完成谁先执行),在继续解析HTML。加载完毕后立即执行,这导致async属性下的脚本是乱序的,对于script有先后依赖关系的情况,并不适用

注意:JS是单线程的,JS解析线程和DOM解析线程共用同一个线程,JS执行和HTML解析是互斥的,加载资源可以并行

prefetchdns-prefetch分别是什么
preloadprefetch
  1. preload 资源在当前页面使用,会优先加载。可以指明哪些资源是在页面加载完成后即刻需要的,浏览器在主渲染机制介入前就进行预加载,这一机制使得资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能。需要 as指定资源类型
  2. prefetch 资源在未来页面使用,空闲时加载。其利用浏览器空闲时间来下载或预取用户在不久的将来可能访问的文档
<head>
  <!-- 当前页面使用 -->
  <link rel="preload" href="style.css" as="style" />
  <link rel="preload" href="main.js" as="script" />

  <!-- 未来页面使用 提前加载 比如新闻详情页 -->
  <link rel="prefetch" href="other.js" as="script" />

  <!-- 当前页面 引用css -->
  <link rel="stylesheet" href="style.css" />
</head>
<body>
  <!-- 当前页面 引用js -->
  <script src="main.js" defer></script>
</body>

目前可用的属性类型如下:
audio: 音频文件。
document: 一个将要被嵌入到<frame><iframe>内部的HTML文档。
embed: 一个将要被嵌入到<embed>元素内部的资源。
fetch: 那些将要通过fetch和XHR请求来获取的资源,比如一个ArrayBuffer或JSON文件。
font: 字体文件。
image: 图片文件。
object: 一个将会被嵌入到<embed>元素内的文件。
script: JavaScript文件。
style: 样式表。
track: WebVTT文件。
worker: 一个JavaScript的web worker或shared worker。
video: 视频文件。
dns-preftchpreconnect
  1. dns-pretch DNS预查询
  2. preconnect DNS预连接

通过预查询和预连接减少DNS解析时间

<head>
  <!-- 针对未来页面提前解析:提高打开速度 -->
  <link rel="dns-pretch" href="https://font.static.com" />
  <link rel="preconnect" href="https://font.static.com" crossorigin />
</head>

猜你喜欢

转载自blog.csdn.net/WDJ_webDeveloper/article/details/134220764