DOM和事件对象事件流
一 DOM操作
js 提供了操作页面元素的API。不过这些API不是ES的内容。DOM由w3c组织提供标准。
1.1 什么是DOM
DOM:document object model。文档对象模型。
DOM是页面元素的一种组织方式。它有点类似一个“多维数组”。
从结构上,它有点类似于一棵倒过来的树,因此DOM也称为DOM树。
DOM树的顶层对象是document对象。
DOM中的内容就是html文档的内容,DOM中的内容称之为DOM节点。
1.2 什么是节点
html文档中的所有内容存储在DOM树种,每一项内容,都是DOM的一个节点。
html文档中出现最多的内容是标签,但是标签只是节点的其中一种。
例如:
网页上的一个注释也是一个节点,但是注释不是标签。
文档声明,也是一个节点,但是它不是标签。
节点的类型有12种。但是常见和常用的有以下几种:
document,属性节点,文本节点,注释节点,元素(标签)节点。
节点是一个 js 对象,注意,不是纯对象。节点对象有3个常用属性。
1:nodeName
2:nodeValue
3:nodeType
关于nodeType,需要记忆的:
元素节点的nodeType是1
属性节点的nodeType是2
文本节点的nodeType是3
注释节点的nodeType是8
document节点的nodeType是9
关于nodeName,需要记忆的是:
元素节点的nodeName是全大写的标签名
关于nodeValue,需要记忆的是
文本节点,注释节点,属性节点的值可以通过nodeValue获取
1.3 创建节点
可以通过document.createElement(标签名)来创建元素节点。
可以通过document.createTextNode(文本内容)来创建文本节点。
可以通过document.createComment(注释内容)来创建注释节点。
1.4 插入节点
在父元素中插入任何节点到最后面:父元素.appendChild(子节点);
在父元素中插入任何节点到指定位置:父元素.insertBefore(新节点,老节点)
1.5 删除节点
在父元素中删除任何节点:父元素.removeChild(子节点);
1.6 查找节点
查找子节点:父元素.childNodes
查找子元素:父元素.children
查找属性节点列表:元素.attributes
查找父节点:子元素.parentNode
查找兄弟元素:元素.nextElementSibling 。元素.previousElementSibling
二 事件对象
事件句柄是事件触发的函数。事件句柄是系统自动调用的。
系统在调用事件句柄的同时,会给事件句柄自动传入一个事件对象,这个事件对象可以获取当前事件的很多信息。
// 获取事件对象。
oBtn.onclick = function(ev){
console.log(ev)
}
注意:只能通过事件句柄的形参获取事件对象,你必须非常清楚哪个是事件句柄!
事件对象常用属性:
ev.clientX => 鼠标事件的鼠标相对于视口的横坐标。
ev.clientY => 鼠标事件的鼠标相对于视口的纵坐标。
ev.keyCode => 键盘事件的键盘码。
ev.target => 事件源。(触发事件的标签对象)
三 事件流
什么是事件流? 事件流是一种事件的传递机制。
为什么需要事件传递?因为需要实现事件委托。
为什么要实现事件委托?事件委托性能更好。
事件流因事件传递的方向不同而分为两种:冒泡和捕获。
冒泡事件流由微软公司提出,事件会沿着DOM树,从事件源传递到document。
捕获事件流由网景公司提出,事件会沿着DOM树,从document传递到事件源。
任何浏览器都支持冒泡,但是IE不支持捕获。因此我们习惯使用冒泡事件流。
3.1 事件委托
事件流的最大意义就是用于实现事件委托。
事件委托可以让程序性能更好。
事件委托为什么能够提升性能?
例如,我们有100个li,每个都需要添加事件,正常情况我们需要循环100次,给每个li添加事件。
如果后续新增了li,还需要给新增的li添加事件。这样性能不太好。
如果使用事件委托,则无需给所有的 li 添加事件,转而给 li 的父元素添加事件。
由于事件流的存在,点击 li,事件也会传递给父元素,从而触发父元素的事件句柄。
// 事件委托里,通过ev.target获取被点击的li之元素。
oUl.onclick = function(ev){
ev.target.style.backgroundColor = 'red'
}
事件委托注意事项:
1:给祖先元素添加事件,而不是给子元素添加事件。
2:通过ev.target获取子元素。
3:事件内this指向父元素,ev.target指向子元素。
4:应避免父元素触发事件句柄,因此需要判断事件源的标签类型。
3.2 阻止冒泡
有些时候事件冒泡会给我们带来麻烦。如果需要阻止冒泡:
1:ev.stopPropagation()
2:ev.cancelBubble = true (IE)
3.3 阻止默认事件
浏览器有很多的默认事件,例如右键事件。如果要禁止默认事件:
1:ev.preventDefault()
2:return false