HTML中的JavaScript
从今天开始我们就要正式学习JavaScript
的语法啦,首先我们得知道,JavaScript
跟HTML
是好兄弟~
插个题外话,一开始开发人员为了将JavaScript
插入HTML
可是下了不少功夫,最早是在Netscape Navigator 2
中实现的,然后就被正式加入到HTML
规范里面去了,接下来我们好好讲解一下<script>
这一元素
<script>
身世揭秘
async
:说实话作者第一次看到这个也是很蒙圈,后来通过查阅官方文档得到了答案:这一属性表明立即开始下载脚本,但是不能阻止其他页面的动作,比如下载资源,只针对外部脚本文件有效(感觉没啥用)charset
:这个属性可就有意思了,相信学过MySQL、Java
的同学对这一属性并不陌生,charset
这个单词跟字符集挂钩,因此这个属性是可选的,我们可以使用src
(下文会介绍)属性指定的代码字符集crossorgin
:这玩意咱一般用不到,知道它是用于配置相关请求的CORS(跨源资源共享)设置就行啦defer
:这一属性表示脚本可以延迟到文档完全被解析和显示之后在执行,同样只对外部脚本文件有效(跟async
一伙的,但是咱写代码不怎么用的到)integrity
:又是个用不到的玩意,说白了跟加密签名有关,平时咱也接触不到.....language
:这个看起来耳熟能详,实际上已经被浏览器弃用了(真可怜),大多数浏览器都会忽略这个属性,不再使用它src
:表示要导入的外部外码文件,这个比较好理解,毕竟咱学过HTML
type
:这个属性可以代替language
,表示代码块中脚本语言的内容类型,按照惯例,我们都是默认text/JavaScript
,虽然它已经废弃了,但是我们的JavaScript
文件的MIME类型通常是application/x-JavaScript
,但是如果这个值是module
,则会被当成ES6
模块,只有在这种情况下,我们才能使用import
跟export
关键字(读者看不懂这段话也没关系,记住有type
这个属性值就可以咯)
使用<script>
有两种方式:
① 通过它直接在网页中内嵌JavaScript
代码
② 导入外部JavaScript
文件
<script> function sayScript() { console.log("Hello World!") } </script>
通过上面的代码我们可以直观的看到一个JavaScript
语言的执行,解释器首先会寻找<script>
,找到之后开始由上往下执行里面的代码。在代码块中我们定义了一个函数(后续会学)用于输出Hello World
,值得一提的是,在<script>
元素中的代码被计算完成之前,页面的其余内容不会被加载,也不会被显示
危险危险危险!!!
<script> function sayScript() { console.log("</<script !src=" "></script>>") } </script>
当我们尝试着在<script>
里面写入</script>
时候,系统会自动识别当成结束的</script>
,想要避免这个问题,我们加入``就可以了
<script> function sayScript() { console.log("</script>") } </script>
加上之后变成上图这样就可以啦~
引入外部JavaScript文件
我们可以通过src
引入外部文件,这个属性的值是URL
,指向包含JavaScript
代码的文件
<script src = "demo.js"></script>
上方代码加载了一个叫demo.js
的外部文件,文件本身只需要包含要放在<script>
的起始及结束标签中间的JavaScript
代码,在解释外部JavaScript
文件时,页面会阻塞。在XHTML
文档中,可以忽略结束标签
注意!!!!
如果咱使用了src属性的<script>
元素,不应该再在<script>
和</script>
标签中再包含其它JavaScript
代码,如果两者都提供的话,浏览器只会下载并执行脚本文件,从而忽略行内代码
作者认为<script>
元素一个很强大的地方就是它可以包含来自外部域的JavaScript
文件,可以是一个完整的URL
,而且这个URL
指向的资源可以跟包含它的HTML
页面不在同一个域中
<script src = "https://www.baidu.com/search.js"><script>
浏览器在解析这种资源的时候,会向src
属性指定的路径发送一个GET请求,从而获取相应资源,假定是一个JavaScript
文件发送请求,但是仍然受到父页面HTTP/HTTPS
协议的限制
其实说白了,上面的看不懂也没啥太大的影响,代码才是灵魂~
标签位置
As we known,过去所有的<script>
元素都会被放在<head>
标签内,如下方代码块所示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> <script src="demo1.js"></script> <script src="demo2.js"></script> </script> </head> <body> <!--这里是标签内容--> </body> </html>
大坑!!!
这种做法主要是把CSS
和JavaScript
集中放到一起导入。不过既然你选择了这么做,也就意味着你必须先把所有的JavaScript
代码先下载、解析和解释完成之后才能渲染页面(浏览器解析到<body>
的起始标签才开始渲染),对于一些大型前端项目,会用到很多JavaScript
外部文件,这会导致渲染的时间加长,从而会出现浏览器界面空白的情况发生
解决办法~
为了解决咱这个问题,我们会把所有的JavaScript
外部文件放在<body>
元素中的页面内容后面,类似于下面这样
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="demo1.js"></script> <script src="demo2.js"></script> </body> </html>
这样一来,浏览器解析<body>
就会更快啦,因为页面会在处理JavaScript
代码之前完全渲染页面~
推迟执行脚本
作者第一次看到这个觉得现在学这个未免有点早了,不过还是讲一下吧
执行脚本的陈年旧事
HTML 4.01为<script>
元素定义了一个叫defer
的属性,这个属性表示脚本在执行的之后不会改变页面的结构,换句话说,只要在<script>
元素上设置defer
属性,相当于告诉浏览器立即下载,但是延迟执行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="demo1.js"></script> <script src="demo2.js"></script> </body> </html>
接着我们看上图,虽然这个里面的<script>
元素包含在页面的<head
中,但是它会在浏览器解析到结束的</html>
标签后才会执行。但是咱HTML5
规范要求脚本应该按照他们出现的顺序执行,因此第一个推迟的脚本会在第二个推迟的脚本之前执行(毕竟咱还是要遵守HTML5的规矩嘛~)
就像上面说的,defer
属性只对外部脚本文件有效,这个是HTML5
中明确推荐的,但是在咱们开发习惯中,我们还是要把推迟执行的脚本放在页面底部比较好
异步执行脚本的那些事
由上文可知,HTML5
为<script>
元素定义了一个叫async
的属性,咋一看async
跟defer
的属性类似,都适用于外部脚本
注意注意!!!!
与defer
不同的是,标记为async
的脚本并不能按照它们出现的次序执行