DOM总结
DOM知识总结
DOM简介
文档对象模型(简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或XML)的标准==编程接口==,通过这些DOM接口可以改变网页的内容、结构、样式。
包括内容:
- 文档:一个页面就是一个文档,DOM中使用document表示
- 元素:页面中的==所有标签==都是元素,DOM中使用element表示
- 节点:页面中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM把以上内容都看做是==对象==
获取页面元素
DOM在实际开发中主要用来操作元素
获取页面中元素可以使用以下几种方式:
1. 获取ID获取
getElementById()
1 | <body> |
- 文档是从上往下加载,所以script写到标签的下面
- get获得 element元素 by通过 采用驼峰命名法
- 参数id是大小写敏感的字符串
- 返回的是一个元素对象
- console.dir() 打印我们返回的元素对象,更好的查看里面的属性和方法
2. 根据标签名获取
getElementByTagName()
- 可以返回带有指定标签的==对象的集合==,以==伪数组==的形式存储
- 想要依次打印里面的元素对象可以采取数组遍历的方式
- 如果页面中没有元素,返回的是空的伪数组的形式
1 | <body> |
3. 通过HTML5新增的方法获取
1. getElementByClassName(“类名”)
根据==类名==返回元素对象集合
2. querySelector(“选择器”)
根据==指定选择器==返回==一个==元素对象
里面的选择器需要加符号 .box
、#nav
3. querySelectorAll(“选择器”)
根据==指定选择器==返回==所有==元素对象
1 | // |
4. 特殊元素获取
获取body元素
1
document.body //返回body元素
获取html元素
1
document.documentElement //返回html对象元素
1.
元素操作
DOM操作可以改变网页内容、结构和样式,可以利用DOM操作元素来改变元素里的内容、属性等
1. 修改元素内容
element.innerText
从起始位置到终止位置的内容,但会去除html标签。同时空格和换行也会去掉
element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
innerText与innerHTML区别:
- innerText不识别html标签(非标准),innerHTML识别html标签(W3C标准)
- innerText去除空格和换行,innerHTML保留空格和换行
2. 修改元素属性
可以修改元素的属性,像元素的id、class、src、href、title等
1 | <body> |
3. 修改表单属性
修改表单的type、value、checked、selected、disabled属性
1 | <body> |
4. 修改样式属性
通过JS修改元素的大小、颜色、位置等样式
1. element.style行内样式操作
2. element.className类名样式操作
1 | <body> |
注意:JS修改style样式操作,产生的是行内样式,且样式采用驼峰命名法 ,适用于修改样式较少的情况下,当修改样式较多时,修改类名,并重新用CSS写修改样式(如果要保留原先的类名,可以采用多类型选择器的方法命名)
5. 自定义属性
自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中
- 设置元素的属性值
element.属性 = ‘值’;
element.setAttribute(‘属性’, ‘值’)
H5规定自定义属性打他-开头作为属性名并且赋值
1 | <div data-index="1"></div> |
- 获取元素的属性值
element.属性 //获取属性值
element.getAttribute(‘属性’);
区别:
element.属性 获取==内置属性值==(元素本身自带的属性)
element.getAttribute(‘属性’); 主要获得==自定义的属性值==(标准)程序员自己添加的,称为index
- removeAttribute移除自定义属性
1 | var div = document.querySelector('div'); |
节点操作
1.节点概述
网页中所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node来表示。HTML DOM树中所有节点均可通过JavaScript进行访问,所有HTML元素(节点)均可被修改,也可以创建和删除
2. 节点操作的原因
获取元素的方法,逻辑性不强,并且获取元素很繁琐。而利用节点层级关系,我们可以利用元素间的父子或兄弟关系更简单的获取,逻辑性更强,缺点就是兼容性稍差。
3. 父子节点
1.Node.parentNode 获得Node节点的父节点
1 | //1.父节点 parentNode |
2.Node.childNodes[n] 获得Node节点的第n+1个子节点(因为下标从0开始)
- firstChild 第一个节点 不管是文本节点还是元素节点
- firstElementChild 返回第一个==子元素节点==
1 | console.log(ol.firstChild); |
1 | var ul = document.querySelector('ul'); |
4. 兄弟节点
1.node.previousElementSibling 获得当前元素的上一个兄弟节点
2.node.nextElementSibling 获得当前元素的下一个兄弟节点
1 | var box1 = document.querySelector('.box1'); |
找不到则返回null,包含所有的节点
5. 创建添加节点
- 创建节点
document.createElement(‘nodeName’)创建一个nodename节点
- 添加节点
1.Node.appendchild(child) 给父节点Node添加子节点child
添加到子节点列表==末尾==
2.Node.insertBefore(child,指定子节点) 给父节点的指定子节点之前添加一个子节点child
将一个节点添加到父节点的==指定子节点前面==
1 | var li = document.creatElement('li'); // 创建新的节点元素 |
想要页面添加一个新的元素:1. 创建元素 2. 添加元素
6. 删除节点
Node.removeChild(‘NodeName’) 删除父节点node的子节点
1 | var ul = document.querySelector('ul'); |
7. 复制节点
Node.cloneNode(Boolean) 复制Node节点
如果括号里Boolean等于true,则为深拷贝(复制标签及里面的内容),如果不填或者为false,则为浅拷贝(只复制标签不复制里面的内容)
1 | var box = document.querySelector('.box'); |
8. 动态创建元素
document.write()
直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
element.innerHTML
将内容写入某个DOM节点,不会导致页面全部重绘
创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
document.createElement()
创建多个元素效率稍低一点,但是结构更清晰
总结:不同浏览器下,==innerHTML效率要比createElement高==
1 | //1.document.write() |
==9.总结==
操作 | 方式 |
---|---|
创建 | 1. document.write 2. innerHTML 3. createElement |
增 | 1. appendChild 2. insertBefore |
删 | 1.removeChild |
改 | 主要修改dom的元素属性,dom元素的内容、属性,表单的值等 1. 修改元素属性:src、href、title等 2. 修改普通元素内容:innerHTML、innerText 3. 修改表单元素:value、type、disabled等 4. 修改元素样式:style、className |
查 | 主要获取查询dom的元素 1. DOM提供的API方法:getElementByld、getElementsByTagName古老用法不太推荐 2. H5提供的新方法:querySelector、.querySelectorAll提倡 3. 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling)提倡 |
操作属性 | 主要针对于自定义属性 1. setAttribute:设置dom的属性值 2. getAttribute:得到dom的属性值 3. removeAttribute移除属性 |
事件处理
1. 事件基础
- 事件的组成:事件源、事件类型、事件处理程序(也称事件三要素)
- 事件源 事件被触发的对象
1 | var btn = document.getElementById('btn'); |
- 事件类型 如何触发 什么事件
- 事件处理程序 通过一个函数赋值的方式完成
1 | btn.onclick = function() { |
执行事件的步骤
获取事件源
注册事件(绑定事件)
添加事件处理程序(函数赋值)
2. 事件高级
1. 注册事件
给元素添加事件,称为注册事件或者绑定事件,有两种方式:==传统方式、方法监听注册方式==
1. 传统注册方式
- 利用on开头的事件,如onclick
- 可以行内添加,如
<button onclick="alert('hello world')"></button>
- 可以封装函数,如btn.onclick()=function(){}
- 特点:注册事件具有唯一性,同一个元素同一个事件只能设置一个处理函数,后注册的函数会覆盖前面注册的函数
2. 方法监听注册方式
- W3C标准推荐方式
- 通过 addEventListener(事件属性,事件处理,事件流) 方法实现
- IE9之前不支持此方法,可使用attachEvent()代替
- 特点:同一个元素同一个事件可以注册多个监听器,它们按照注册的顺序依次执行
eventTarget.addEventListener(type, listener, useCapture)
type:事件类型字符串,比如click、mouseover,注意==不带on==
listener:事件处理函数,事件反生是,会调研该监听函数
useCapture:可选参数,是一个布尔值,默认是false。
1 | var btns = document.querySelectorAll('button'); |
2. 删除事件
1.传统注册方式
Event.οnclick=null;
2.方法监听注册方式
Event.removeEventListener(‘click’,fn);
1 | var divs = document.querySelectorAll('div'); |
3. DOM事件流
事件流描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
DOM事件流分为3个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
事件捕获:网景最早提出,由DOM==最顶层节点开始==,然后逐级向下传播到最具体的元素接收的过程
事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程
1 | //1.JS代码中只能执行捕获或者冒泡其中的一个阶段 |
1. 在实际开发中很少使用事件捕获,更关注事件冒泡
2.有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
4. 事件对象
- event就是一个事件对象 写到监听函数的小括号里面 当形参来看
- 事件对象只有有了事件才会存在,是系统自动创建的,不需要我们传递参数
- 事件对象 是事件的一系列相关数据的集合,跟事件的状态,比如键盘按键状态、鼠标的位置、鼠标按钮的状态
简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,他有很多属性和方法
- 这个事件对象也可以自己命名 比如event、e(最常用)
- 事件对象也有兼容性问题 通过Windows.event兼容性的写法 e = e|| window.event;
1 | var div = document.querySelector('.div'); |
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 (标准) |
e.srcElement | 返回触发事件的对象 (非标准ie678使用) |
e.type | 返回事件的类型 比如click mouseover不带on |
e.cancelBubble | 该属性阻止冒泡 (非标准ie678使用) |
e.returnValue | 该属性阻止默认事件 (非标准)如不让链接跳转 |
e.preventDefault() | 该属性阻止默认事件 (标准)如不让链接跳转 |
e.stopPropagation() | 阻止冒泡 (标准) |
1 | //1. e.target 返回的是触发事件的对象||this返回的是绑定事件的对象 |
①阻止默认行为
1 | var a = document.querySelector('a'); |
②阻止事件冒泡
标准写法:利用事件对象里面的stopPropagation()方法
e.stopPropagation()
非标准写法:IE678利用事件对象cancelBubble属性
1 | var father = document.querySelector('.father'); |
③事件委托
原理:不是每个子节点单独设置事件监听器,而是将事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
以上案例:给ul注册点击事件,然后利用事件对象的target来找到当前点击的Ii,因为点击Ii,事件会冒泡到ul上有注册事件,就会触发事件监听器
作用:只操作了一次DOM,提高了程序的性能
5. 常用鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
==使用监听注册时去掉前面 ‘on’==
- 禁止鼠标右键菜单
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
document.addEventListener(‘contextmenu’, function(e) {
e.preventDefault();
})
- 禁止鼠标选中
document.addEventListener(‘selectstart’, function(e) {
e.preventDefault();
})
- 获得鼠标坐标
鼠标事件 | 触发条件 |
---|---|
e.clientX | 返回浏览器相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回浏览器相对于浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标 (IE9+支持) |
e.pageY | 返回鼠标相对于文档页面的Y坐标 (IE9+支持) |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
- 常用键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发 但是它不识别功能键 ctrl shift等 |
当按下一个按键再松开时,三个事件的执行顺序依次为:
onkeydown ->onkeypress->onkeyup
==使用监听注册时去掉前面 ‘on’==
键盘事件对象属性:keyCode
说明:返回该键的ASCII值
注意:
- keyup和keydown事件不区分字母大小写,如a和A得到的都是65
- keypress事件区分字母大小写