前言
在很久之前就遇到了这个问题,由于代码段放的位置不对导致代码段无法生效。所以这次就简单写一下代码段不同位置的区别。
正文
JavaScript
JS是一种解释性脚本(不进行预编译)
高级语言的两种翻译方式:
- 编译
以基本的C语言为例,大部分语言是直接通过编译器将高级语言编译成为机器可以懂的机器语言(二进制文件 .exe)。但是也有不一样的,比如JAVA这种跨平台语言,它是将高级语言先编译成为JAVA虚拟机能够识别的class文件,在不同的平台上再编译为相应的机器语言,实现跨平台。
- 解释
解释性脚本脚本不需要编译,在执行时才进行解释。解释性脚本语言有专门的解释器,不过每次执行时都需要编译,所以效率比较低。
JavaScript也有自己的解释器–JavaScript引擎,他是浏览器的一部分。
HTML 语言的执行顺序
作为一门解释性脚本语言,它的执行顺序是从前到后顺序执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="jquery-1.8.3.js"></script>
<title>Html页面内容执行顺序</title>
<style></style>
</head>
<body>
<script type="text/javascript">
var userId = $('#hiddenUserId').val();
var contextPath = $('#hiddenContextPath').val();
var userName = $('#hiddenUserName').val();
alert(userName);
</script>
</body>
</html>
按照顺序执行,先解析该文档为HTML文档,接着解析head部分的script脚本,head部分的style样式,接着渲染body部分,接着解析body中的script脚本。
按照以上顺序,我就可以理解为什么我上一次引用的验证码脚本以及vue框架放在HTML中head部分时,无法生效。原因是在于如果将脚本放在head中,script脚本执行时DOM树还没有被渲染,所以脚本是无法执行对DOM进行修改的。而如果将脚本放在body尾部,执行此脚本时,DOM树已被渲染完毕,所以可执行修改操作。
结论
1.head中所放的JavaScript代码段主要功能应该是不会在页面加载时就进行执行的脚本功能,即后续通过其他操作触发的(比如onclik按键触发),这类脚本可以预先解释,在需要时再执行
2.body后面放的脚本应该是页面加载时就要触发的脚本,比如对DOM数内容的初始化(向上面的验证码系统,vue的脚本)
特殊情况##
以下情况可以改变JS代码的执行顺序
- window.onload:等到页面中的所有内容加载完成后才会执行。
- $(document).ready():页面中所有的DOM结构绘制完成后就能够执行。
- script脚本中,大部分浏览器支持async和defer属性。
async表示的意思是异步加载JavaScript文件,它的下载过程可以在HTML的解析过程中进行,加载完成之后立即执行这个文件的代码,执行文件代码的过程中会阻塞HTML的解析,它不保证文件加载的顺序。
defer表示的意思是在HTML文档解析之后在执行加载完成的JavaScript文件,JavaScript文件的下载过程可以在HTML的解析过程中进行,它是按照script标签的先后顺序来加载文件的。
参考资料: