1、浏览器的加载过程:
以CSS在<head>
标签(<body>
之前)中以外部文件的方式引用、JavaScript在<script>
标签(</body>
之前)中以外部文件的方式引用为例。
1. 浏览器向服务器发送请求,服务器返回HTML文件(以HTML页面为例);
2. 浏览器开始加载HTML代码(自上而下依次解析):
如对以下的代码,浏览器的解析器可以翻译成DOM树如图1所示。
<html>
<body>
<p>Hello World</p>
<div> <img src="hello.png"/></div>
</body>
</html>
3.遇到<link>
标签时,浏览器对服务器发出请求来请求对应的CSS文件:
如对以下的CSS代码,浏览器的CSS解析器生成CSS树如图2:
p,div {
margin-top: 3px;
}
.error {
color: red;
}
4.遇到<body>
后,浏览器开始构建呈现树(Render tree):
浏览器通过呈现器(WebKit称为 呈现器 或 呈现对象 ,Firefox称为 框架 )来进行布局和将自身和子元素绘制出来。如图3所示,呈现器以3个对象 -- DOM节点、节点的样式和节点的堆叠顺序(z-index)为基础。
5.遇到
<script>
后,浏览器阻塞页面的解析以及其他资源的下载(如图片,音乐等),直到JS文件加载执行完毕。href
为异步加载-不会阻塞页面的渲染(因为CSS无法对DOM树进行修改),src
则为同步加载。这也是为什么不推荐CSS文件通过 @import 方式(同步加载)引入的原因之一。
6.资源都加载完毕后,页面完全呈现。
[参考]: https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/
2、document.ready 和 document.onload :
document.ready 为文档结构已经加载完成(不包含图片等媒体文件)。
document.onload 为文档结构加载完成,且媒体资源也都加载完成。
3、事件冒泡与捕获:
事件冒泡:
事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。子元素的 onclick 事件触发之后,父元素的 onclick 事件也被触发;依次类推,直到document对象。如下面的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Item</title>
<style>
body {
background-color: yellow;
}
div {
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div>
<input type="button" value="click"/>
</div>
<script>
var input = document.getElementsByTagName("input")[0];
var div = document.getElementsByTagName("div")[0];
var body = document.getElementsByTagName("body")[0];
input.onclick = function() {
console.log("1");
}
div.onclick = function() {
this.style.backgroundColor = "red";
console.log("2");
}
body.onclick = function() {
console.log("3");
}
document.onclick = function() {
console.log("4");
}
</script>
</body>
</html>
input
的 onclick
事件被触发之后,其父级元素 div
的 onclick
事件也被触发;依次类推,直到 document
(根结点)的 onclick
事件也被触发。
阻止事件冒泡:
对上例的 onclick
事件添加 stopPropagation
方法来阻止事件传播:
input.onclick = function(e) {
var e = e || window.e;
console.log(1);
e.stopPropagation();
}
即可阻止事件的冒泡 ( e 代表事件对象,即事件驱动源;保存了当前事件元素的信息,如鼠标的坐标信息 e.pageX & e.pageY 。window.event 为 低版本IE 中的对象)。
事件捕获
与事件冒泡相反,onclick
事件从顶层元素(document)触发到目标元素:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Item</title>
<style>
body {
background-color: yellow;
}
div {
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div>
<input type="button" value="click"/>
</div>
<script>
var input = document.getElementsByTagName("input")[0];
var div = document.getElementsByTagName("div")[0];
var body = document.getElementsByTagName("body")[0];
input.addEventListener("click", function(e) {
var e = e || window.event;
console.log(1);
}, true);
div.addEventListener("click", function(e) {
console.log(this.style.backgroundColor);
this.style.backgroundColor = "red";
console.log("2");
}, true);
body.addEventListener("click", function(e) {
console.log("3");
}, true);
document.addEventListener("click", function(e) {
console.log("4");
}, true);
</script>
</body>
</html>
为 addEventListener
设置第三个参数 true
即采用事件捕获方式( 没有 和 设置为 false 则为采用事件冒泡方式)。
事件捕获的阻止
对 click
事件添加 stopPropagation
方法会使事件停留在当前层:
document.addEventListener("click", function(e) {
console.log("4");
e.stopPropagation();
}, true);
如在 document
的 click
事件中添加 stopPropagation
方法会使事件捕获被阻止,即点击目标元素只会触发到 doucment
的 click
事件。
4、title 和 alt 的区别:
title 作为属性使用时,用来为元素提供额外说明信息。
alt 为特殊标签(img、area、input)设置标签无法显示时的替换文字。
5、强制类型装换、显式装换、隐式装换:
强制类型转换:
Boolean():Boolean(0) // false-0
Number():Number(undefined) // NaN
Number(null) // 0
String():String(null) // "null"
parseInt()、 parseFloat():
JSON.parse()、JSON.stringify():
显式类型装换:
用强制类型装换运算符将某一类型的数据装换为另外一种类型的数据。
隐式类型装换:
不同类型的数据在做算术运算时,JavaScript解释器 会在运算前对它们进行
隐式类型装换。
如:typeof(1 + '') // string
typeof('123' - 1) // number
6、call & apply & bind:
函数实例的 call
和 apply
方法都可以指定函数内部 this
(函数执行时的作用域)的指向 ,然后在指定的作用域中调用该函数。
俩个方法的第一个参数为要指定的为函数 this
的对象,如果为 空、null
或 undefined
则默认传入全局对象。call
后面还可以接收多个参数作为函数调用时的参数;apply
则第二个参数为一个数组来存放作为函数调用时的参数。
函数实例的 bind
方法为将函数内部 this
绑定在某个对象上,然后返回一个新的函数。bind
方法的第一个参数为 this
要绑定的对象,如果为 空、null
或 undefined
则默认传入全局对象;还可以接收多个参数来绑定原函数的参数。还有,最好设置一个对象来接收新产生的匿名函数。
[参考]: http://javascript.ruanyifeng.com/oop/this.html
7、JavaScript 的数据类型
JavaScript 的数据类型可以分为 6 + 1 种:
1、数值:
2、字符串:
3、布尔值:
4、对象:
5、undefined:
6、null:
7、Symbol:
其中 对象 还可以分为 数组、函数、两者之外的对象 这三个子类型;null 和 undefined 一般视为特殊值。Symbol 为 ES6 中新加入的一种原始数据结构。
在 JavaScript 中,可用 typeof
来返回一个值的数据类型;对于 数值、字符串、布尔值、undefined 会正确的返回对应的 number
、string
、boolean
、undefined
(可利用 typeof 来判断变量是否被声明)。对于 对象 中的 函数 也会正确的返回 function
,但 数组 会返回为 object
;而且 null 也会返回为 object
(历史问题,虽然 null 不是对象)。
null 和 undefined 的区别在于 null
表示为“空”,转化为 数值
时为 0
;undefined 表示“未定义”,转化为 数值
时为 NaN
。
8、字符串的比较大小
字符串的大小比较是根据字符串从高位开始比较,一旦某一位的值不同,及比较出大小,跟字符串的位数无关。如:
'300' > '10000' //true