DOM(Document Object Model)
-
DOM 是Javascript操作网页的接口,全称是 文档对象模型。它的作用是将网页转为一个Javascript对象,从而可以用脚本进行各种操作。
-
DOM的最小组成单位是节点,节点的七种不同类型:
Document:整个文档树的顶层节点 DocumentType:doctype标签(比如<!DOCTYPE html>) Element:网页的各种HTML标签(比如<body>、<a>等) Attribute:网页元素的属性(比如class="right") Text:标签之间或标签包含的文本 Comment:注释 DocumentFragment:文档的片段 -
childNodes 返回的是一个伪数组
-
DOM树是人对dom的理解,并不是存在内存中的,但是程序员最主要的工作就是操作内存,那么DOM树是如何存在在内存中的呢? 那么在内存中就是以对象形式存在的,html对应一个对象,head对应一个对象,body对应一个对象,这些对象与DOM树是一一对应的,这就是model模型,document--model--object 这三个就是形成了DOM
-
html 是 document标签, body,head ,p ,div 等是element元素(标签),类似于div里面的 文本 就是text元素(标签)。html是Document构造出来的, body head p div等等是Element构造出来,文本标签就是由Text构造出,这三种类型的共同祖先就是Node.
-
Node 分为 Document(html)、Element(元素)和 Text(文本),以及其他不重要的(比如注释之类的)。
-
页面上的所有的标签都会对应一个构造函数,那么浏览器在看到某个标签的时候,就会用他的构造函数构造出对应的一个内存中的对象。这就是DOM的主要功能。
-
如果想要改页面的html,就可以调用这个节点在内存中的对象,然后调用这个对象的api,这样就可以改页面的html了
-
DocumentFragment优化 重点考点
-
cloneNode()方法
<body>
<div id="div1">1111</div>
</body>
var div2 = div1.cloneNode();
document.body.appendChild(div2);
那么会得到
<body>
<div id="div1">1111</div>
<div id="div1"></div>
</body>
如果给cloneNode()传个参数true,就是代表要深拷贝
那么得到的结果就是:
<body>
<div id="div1">1111</div>
<div id="div1">111</div>
</body>
选择深拷贝的话,则节点的所有后代节点都会被克隆,如果为false的话,则只克隆节点本身。
- innerText()和contentText()的区别? NodeType=1 和NodeType = 3分别代表什么? 1: 元素节点 2. 属性节点 3. 文本节点 区别是:
DOM事件模型
- DOM事件有 leve0,leve1,leve2,leve3
- leve2 将DOM事件做了很详细的标准说明
```
leve1的点击事件
x.onclick=function() {
console.log(1)
}
level2的点击事件
x.addEventListener('click',function() {
console.log(2)
})
区别是: onclick是属性,是唯一的,如果写了两个onclick事件的话,比如:
x.onclick=function() {
console.log(1)
}
x.onclick=function() {
console.log(2)
}
那么只能打印出2
而addEventListener 可以监听多个 click事件,因为addEventListener事件模型是一个队列
x拥有一个eventListeners的队列,可以往里面 通过addEventListener 往里面添加事件,以上的就是添加了两个click事件,遵循先进先出的
原则,所以先打出1 再打印出2
如果要移除监听就可以用removeEventListener()
```
- 事件冒泡
<div id="parent">
爷爷
<div id="father">
爸爸
<div id="son">
儿子
</div>
</div>
</div>
parent.addEventListener('click',function() {
console.log('爷爷')
},true);
father.addEventListener('click',function() {
console.log('爸爸')
},true);
son.addEventListener('click',function() {
console.log('儿子')
},true);
以上代码,当点击儿子的时候,那么打印出来的是:爷爷,爸爸,儿子
如果不传addEventListener中第三个参数不传,或者传的是false,
那么打印出来的是 儿子,爸爸,爷爷
如果只有爷爷的传了true,那么打印出来的就是 爷爷,儿子,爸爸
跟代码执行顺序没有关系。
但是如果监听的是同一个元素,比如:
son.addEventListener('click',function() {
console.log('儿子1')
},true);
son.addEventListener('click',function() {
console.log('儿子2')
},true);
addEventListener的第三个参数不管传没传参数还是传了什么参数,
都会按照代码执行顺序来执行,先打印出儿子1,再打印出儿子2,因为是个队列模型,所以遵循先进先出原则
解析: 当儿子被点击了之后,儿子,爸爸,爷爷都监听到了点击事件,然后都在各自查找自己队列中有没有回调函数要执行,那么各自都有回调函数,是都要执行的,那么现在的问题是谁先执行呢?
首先是从上往下问爷爷,爸爸和儿子,然后再从下往上问儿子,爸爸,爷爷。 每次问的时候,有回调函数的就是要采取行动的,那是第一次问的时候采取行动还是第二次问的时候再采取行动,这个就取决于addEventListener的第三个参数了,如果参数是true那就是第一次问的时候就执行自己的回调函数,如果没有第三个参数或者参数为false的话,那就是第二次的时候再执行回调了。所以,不传参数或者传的是false的时候,就会打印出儿子爸爸爷爷
son.addEventListener('click',function() {
console.log('儿子捕获')
},true);
son.addEventListener('click',function() {
console.log('儿子冒泡')
});
面试题: 如果儿子身上既有捕获阶段(加了参数true就是捕获) 又有冒泡阶段的话,哪个先执行?哪个在前哪个先执行。
如果先触发在本身的话是不区分冒泡还是捕获的
jQuery
jquery其实就是一个构造函数
立即执行函数
立即执行函数,会创建一个作用域,在这个作用域中的变量就不会变成全局变量。
有以下几种:
(function () {
console.log(1)
})()
(function(){
console.log(2)
}())
-function(){
console.log(3)
}()//这里也可以用+,!,~,
es6之后,就可以不用立即执行函数了,可以用{}
{
let a = 1;
}