DOM (冒泡、捕获、点击隐藏浮层)

Document Object Model(文档对象模型)

DOM的主要功能:

页面中的节点(Node),通过构造函数(Document,Element,Text,Comment…等构造函数),构造出对应的对象。
Node也是一个构造函数, 派生于 Object,所以 Node 构造出来的函数,也有 Object 的公有属性。

Node 构造了 Document DocumentType Elment Text Comment DocumentFragment 等类型。

Document 构造了<html>标签。
Element 构造了<head> <body> <meta> <title> <script> <h1>…标签。
Text构造了页面中 文本
Comment构造了页面中 注释


Node 接口

Node 属性:查阅MDN

childNode,fristChild,innerText,lastChild,nextSibling,nodeName,nodeType,nodeValue,outerValue,ownDocument,parentElement,parentNode,previousSibling,textContent

Node 方法:查阅MDN

  • appendChild()添加子元素
  • cloneNode()克隆节点(分true深拷贝false浅拷贝
  • contains()是否包含另一个元素
  • hasChildNodes()是否有子元素,返回一个布尔值
  • insertBefore()把…插到…前面
  • isEqualNode()是否是相等的节点
  • isSameNode()是否是相同的节点(同一个 ‘===’)
  • removeChild()移除子元素(还是存在于内存中)
  • replaceChild()替换子元素()
  • normalize()使…正常

Document 接口

查看document属性 console.dir(document)
Document MDN

Document 属性 查询MDN

body,characterSet,childElementCount,children,doctype,documentElement,domain,fullscreen,head,hidden,images,
links,location,onxxxxxx,origin,plugins,readState,referrer,scripts,scrollingElement,styleSheets,title,visibilityState

Document 方法 查询MDN

  • close()
  • createAttribute
  • createElement

DOM事件 看一下

事件监听
btn.onclick.call(this,arguments)  //this = btn,arguments = 参数

DOM Level 0

onclick onerror onload onmouseenter

html 写法 要加括号

1
onclick = fn()   //fn 类型为字符串

js 写法 不能加括号,调用是时候才加

1
X.onclick = fn    //fn 类型为函数对象

DOM Level 1


DOM Level 2 (最广泛)

(2000/11/13)

  • addEventListener removeEventListener
  • 事件冒泡,事件捕获

addEventListener 可以添加多个 click 方法(队列,先进先出)

1
2
3
4
5
6
7
8
9
// 先打印1,再打印2
xx.addEventListener('click',function(){
console.log(1)
})
xx.addEventListener('click',function(){
console.log(2)
})
// 1
// 2

onclick,属性,唯一(工作中,可能别人也用了onclick,可能会把别人的覆盖)

1
2
3
4
5
6
7
8
// 只打印2,后面`onclick`的把前面的覆盖了
xx.onclick = function(){
console.log(1)
}
xx.onclick = function(){
console.log(2)
}
// 2

DOM Events(先事件捕获,绑定同一对象按代码先后顺序,最后事件冒泡)

注:jQuery 不支持设置 true或false

事件冒泡(从里到外)

false 或者 不填

1
2
3
4
5
6
7
8
9
10
11
12
13
// 点击 里
外.addEventListener('click',function() {
console.log("外")
})
中.addEventListener('click',function() {
console.log("中")
})
里.addEventListener('click',function() {
console.log("里")
})
// 里
// 中
// 外

事件捕获(从外到里)

多加了一个参数 true

1
2
3
4
5
6
7
8
9
10
11
12
13
// 点击 里 
外.addEventListener('click',function() {
console.log("外")
},true)
中.addEventListener('click',function() {
console.log("中")
},true)
里.addEventListener('click',function() {
console.log("里")
},true)
// 外
// 中
// 里

如果同一个事件,绑定了2次,那么就按 先后顺序执行,true,false 失效

先事件捕获,再绑定同一对象按代码先后顺序,最后事件冒泡


点击别处关闭浮层

  • stopPropagation() 阻止传播
  • one('click',function..) 只监听一次

JS(document 随时被监听,如果 popover 有很多,则不节省内存)

查看完整代码

1
2
3
4
5
6
7
8
9
10
11
12
btn.addEventListener('click', function () {
console.log('点击btn')
popover.style.display = 'block'
})
wrapper.addEventListener('click', function (e) {
console.log('点击wrapper')
e.stopPropagation() // 阻止外部传播进来,所以在 document 被点击的时候,wrapper 里面不受影响
})
document.addEventListener('click', function () {
console.log('点击document')
popover.style.display = 'none'
})

JQ(仅仅需要在 popover show() 出来后监听一次,节省内存)

stopPropagation()setTimeout() 这两种方法实现
查看stopPropagation()方法完整代码
查看setTimeout()方法完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//方法一 stopPropagation
// 点击 btn,先后打印 '点击btn' '点击wrapper',同时 popover 也会出现,
// 这时候就开始监听一次 document 的点击事件,点击别处,popover 会隐藏。
{
$(btn).on('click',function () {
console.log('点击btn')
$(popover).show()
$(document).one('click',function () { //只执行一次
console.log('点击document')
$(popover).hide()
})
})
$(wrapper).on('click',function (e) {
console.log('点击wrapper')
e.stopPropagation()
})
}

// 方法二 用 setTimeout,就不需要 stopPropagation 了;
// 点击 btn,打印 '点击btn',同时 popover 也会出现,
// 这时候就开始监听一次 document 的点击事件,点击别处,popover 会隐藏。
{
$(btn).on('click',function () {
console.log('点击btn')
$(popover).show()
setTimeout(function() {
$(document).one('click',function () {
console.log('点击document')
$(popover).hide()
})
},0)
})
}