目录
七.DOM
1.文档对象属性(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口,通过这些DOM接口可以改变网页的内容、结构和样式。
2.获取元素:
(1)通过id获取:document.getElementById(id);
说明:参数id是大小写敏感的字符串,返回的是一个元素对象,输出的是整个id标签;可以通过console.dir()打印返回的元素对象,更好的查看里面的属性和方法。
(2)通过标签名获取某一类标签:document.getElementsByTagName(‘标签名’)
说明:返回的是获取元素对象的集合,以伪数组形式返回,不能使用数组的方法
(3)获取某个父元素内部所有指定标签的子元素:element.getElementsByTagName(‘标签名’)
注意:父元素必须是单个对象,获取的时候不包括父元素自己。
(4)H5新增的方法获取:
①根据类名获取某些元素:document.getElementsByClassName('类名');
②指定选择器返回第一个元素对象:document.querySelector('选择器')
③返回指定选择器的所有元素对象集合:document.querySelectorAll('选择器')
(5)获取特殊元素:
①获取body元素:document.body
②获取html元素:document.documentElement
3.事件基础
(1)事件的三要素:事件源、事件类型、事件处理程序
①事件源:事件被触发的对象
②事件类型:如何触发事件,比如鼠标点击、鼠标经过、键盘按下等等
③事件处理程序:通过一个函数赋值的方式完成
(2)常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
4.操作元素
(1)改变元素的内容
①element.innerText
:从起始位置到终止位置的内容,但它除去html标签,不保留格式
②element.innerHTML
:从起始位置到终止位置的内容,包括html标签,保留格式
注意:这两个属性是可读写的,可以获取元素里面的内容
(2)修改元素属性:例如src、href、alt等等
(3)修改样式属性:element.style
(行内样式)或element.ClassName
(类名样式)
注意:①如果样式修改较多,可以采取操作类名方式修改元素样式;
②class因为是个保留字,因此使用className来操作元素类名属性;
③className会直接更改元素的类名,会覆盖原先的类名
④如果要保留原先的类名,可以this.ClassName='first change'
,类似于多类选择器
(4)获取元素的属性:
①element.属性
:获取内置属性值(元素本身自带的属性)
②element.getAttribute(’属性‘)
:主要获得自定义的属性(标准)
(5)修改元素的属性值:
①element.属性名 = '值'
②element.getAttribute(’属性‘,’值‘)
,如果修改的是选择器,那么’属性’填的是’class’
(6)移除元素属性:element.removeAttribute('属性')
5.H5自定义属性
(1)目的:为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中。
(2)自定义属性是通过getAttribute(‘属性’)获取,但是有些自定义属性很容易引起起义,不容易判断是元素的内置属性还是自定义属性。
(3)H5自定义属性:以data-开头作为属性名并且赋值。使用element.dataset.'data后面的内容'
,如果是类似data-list-time这样的,需要使用驼峰命名法,element。dataset.listName
来获取。
6.节点操作
(1)节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。其中元素节点、属性节点、文本节点(包括换行、空格、文字)的nodeType分别为1,2,3。
(2)获取父节点:node.parentNode
。该属性返回的是node的最近的一个父节点,如果指定的节点没有父节点,则返回null。
(3)获取子节点:
①node.childNodes(标准)
,返回包含指定节点的子节点的集合,该集合为随时更新的集合。返回值中包含了所有的子节点,包括文本节点、元素节点等。如果只想获得里面的元素节点,需要专门的处理,所以一般不提倡使用childNodes。
//获取ul里面的所有li元素
var ul = document.querySelector('ul');
for(var i=0;i<ul.length;i++){
if(ul[i].nodeType == 1){
console.log(ul.childNodes[i]);//元素节点
}
}
②parentNode.children(非标准)
,只读属性,只返回所有的子元素节点,其余元素节点不返回。
③获取第一个子节点:parentNode.firstChild
,包含文本节点、元素节点等;使用parentNode.firstElementChild
或者parentNode.children[0]
,返回第一个子元素节点。
④获取最后一个子节点:parentNode.lastChild
,包含文本节点、元素节点等;使用parentNode.lastElementChild
或者parentNode.children[length-1]
,返回最后一个子元素节点。
(4)获取兄弟节点
①node.nextSibling
,返回当前元素的下一个兄弟节点,包含所有的节点。
②node.nextElementSibling
,返回当前元素的下一个兄弟元素节点,找不到则返回null(兼容性)
③node.previousSibling
,返回当前元素的上一个兄弟节点,包含所有的节点。
④node.previousElementSibling
,返回当前元素的上一个兄弟元素节点,找不到则返回null(兼容性)
//解决兼容性问题
function getNextElementSibling(element) {
var e =element;
while(e=e.NextSibling){
if(e.nodeType == 1){
return e;
}
}
return null;
}
(5)创建、添加、删除、复制节点
①动态创建节点:document.createElement('tagName')
②添加节点:node.appendchild(child)
,将一个节点添加到指定元素的末尾,类似于CSS里面的after伪类元素;node.insertBefore(child,指定元素)
,将一个节点添加到指定元素的最前面,类似于CSS中的before伪类元素。
③删除节点:node.removeChild(child)
,从DOM中删除一个子节点,返回删除的节点。
④复制节点:node.cloneNode()
返回调用该方法的节点的一个副本,如果括号里面为空或者是false,是浅拷贝,只复制标签不复制标签里面的内容;括号里面为true,是深拷贝,则复制标签和标签里面的内容。
(6)创建节点的各类方法的区别:
①document.write
是直接将内容写入页面的内容流,但是在文档流执行完毕,则会导致页面全部重绘(以前的内容都没有了);
②innerHTML
是将内容写入某个DOM节点,不会导致全部重绘,但是采用字符串拼接的形式会使效率非常低。采用数组(push)拼接(join)的方法效率更高,结构稍微复杂。
③creatElement()
创建多个元素效率稍微低一点,但是结构比较清晰。
7.注册事件的两种方式
(1)传统注册方式:利用on开头的事件onclick,注册事件具有唯一性,同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数。
(2)方法监听注册事件:使用addEventListener()
方法,同一个元素同一个事件可以注册多个监听器,按照注册顺序执行但是IE9以下的版本不支持此方法,可以用attachEvent()代替。
①格式:eventTarget.addEventListener(type,listener[,useCapture])
,将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数 。
②参数说明:
- type:事件类型字符串,比如click、mouseover,注意这里不带on,要加引号
- listener:事件处理函数,事件发生时,会调用该监听函数
- useCapture:可选参数,是一个布尔值,默认是false。
③注册事件兼容性解决方案
// 注册事件兼容性解决方案
function addEventListener(element,eventName,fn){
// 判断当前浏览器是否支持addEventListener这个方法
if(element.addEventListener){
element.addEventListener(eventName,fn);
}else if(element.attachEvent){
element.attachEvent('on'+eventName,fn);
}else{
// 相当于element.onclick = fn
element['on'+eventName] = fn;
}
}
8.删除事件
(1)传统注册方式:eventTarget.onclick = null
(2)方法监听注册方式:eventTarget.removeEventListener(type,listener[,useCapture)
,使用IE9以下的版本为eventTarget.detachEvent(eventNameWithOn,callback)
。
注意:linstener监听函数根据需求来写,可以自己删除自己,将函数单独创建再调用。
9.DOM事件流
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
(1)DOM事件流的三个阶段:
①捕获阶段:由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程。(从外向内)
②当前目标阶段
③冒泡阶段:事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程。(从内向外)
(2)注意:①JS代码中只能执行捕获或者冒泡其中的一个阶段;
②onclick和attachEvent只能得到冒泡阶段
③addEventListener(type,listener[,Capture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(默认),表示事件冒泡阶段调用事件处理程序。
10.事件对象:处理函数function(event){}中的event就是事件对象。event对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。在事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象中。
注意:event是一个形参,系统帮我们设定为事件对象,不需要传递实参过去。当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器。(事件处理函数)
(1)常见的事件对象的属性和方法
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象(标准) |
e.srcElement | 返回触发事件的对象(非标准ie6-8使用) |
e.type | 返回事件的类型,比如click mouseover 不带on |
e.cancelBubble | 阻止冒泡(非标准ie6-8使用) |
e.returnValue | 阻止默认事件(非标准ie6-8使用) |
e.preventDefalt() | 阻止默认事件(标准)比如不让链接跳转 |
e.stopPropagation() | 阻止冒泡,标准 |
①target和this的区别:e.target点击了哪个元素就返回哪个元素;this哪个元素绑定了这个点击事件就返回谁。 | |
(2)常用的鼠标事件 | |
①禁止鼠标右键菜单:contextmenu 主要控制应该何时显示上下文菜单,主要用于程序猿取消默认的上下文菜单。 |
document.addEventListener('contextmenu',function(){
e.preventDefalt();
})
②禁止鼠标选中(selectstart开始选中)
document.addEventListener('selectstart',function(){
e.preventDefalt();
})
(3)鼠标事件对象:MouseEvent
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视化的X坐标 |
e.clientY | 返回鼠标相对于浏览器可视化窗口的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标(IE9+支持) |
e.pageY | 返回鼠标相对于文档页面的Y坐标(IE9+支持) |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
(4)常用的键盘事件 | |
键盘事件 | 触发条件 |
– | – |
onkeyup | 某个键盘按键送开时触发 |
onkeydown | 某个个键盘按键按下时触发 |
onkeypress | 某个键盘按键被按下时触发,但是它不识别功能键,比如ctrl shift等 |
注意:当使用addEventListener()方法时不加’on’。 | |
三个事件的执行编译:keydown–keypress–keyup | |
(5)键盘事件对象中的e.keyCode属性可以得到相应键的ASCAII码值,其中keyup和keydown事件不区分字母大小写,keypress事件区分字母大小写 |
11.事件委托(重点)
(1)原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。只操作一次DOM,提高程序的性能。