DOM

Lán2022年11月2日
大约 8 分钟

DOM

DOM(Document Object Model,文档对象模型)是JavaScript操作HTML文档的接口,使文档操作变得非常优雅、筒便。

DOM最大的特点就是将文档表示为节点树。

访问节点

document对象是DOM中最重要的东西,几乎所有DOM的功能都封装在了document对象中

document对象也表示整个HTML文档,它是DOM节点树的根

document对象的nodeType属性值是9

getElementById 方法,通过id得到元素
getElementsByTagName 方法,通过标签名得到元素组
getElementsByClassName 方法,通过类名得到元素组
querySelector 方法,通过选择器得到元素
querySelectorAll 方法,通过选择器得到元素组

访问HTML元素最常用的方法是使用元素的id。

innerHTML 属性

获取元素内容最简单的方法是使用 innerHTML 属性。

改变元素节点中的内容

改变元素节点中的内容可以使用两个相关属性

  • innerHTML
  • innerText

innerHTML属性能以HTML语法设置节点中的内容

innerText属性只能以纯文本的形式设置节点中的内容

添加和删除元素

document.createElement()方法用于创建一个指定tag name的HTML元素

var oDiv = document.createElement('div');

新创建出的节点是“孤儿节点”,这意味着它并没有被挂载到DOM树上,我们无法看见它

必须继续使用appendChild()或insertBefore()方法将孤儿节点插入到DOM树上

任何已经在DOM树上的节点,都可以调用appendChild()方法,它可以将孤儿节点挂载到它的内部,成为它的最后一个子节点

父节点.appendChild(孤儿节点);

任何已经在DOM树上的节点,都可以调用insertBefore()方法,它可以将孤儿节点挂载到它的内部,成为它的“标杆子节点”之前的节点

父节点.insertBefore(孤儿节点,标杆节点);

移动节点

如果将已经挂载到DOM树上的节点成为appendChild()或者insertBefore()的参数,这个节点将会被移动

新父节点.appendChild(已经有父亲的节点);
新父节点.insertBefore(已经有父亲的节点,标杆子节点);

这意味着一个节点不能同时位于DOM树的两个位置

删除节点

removeChild()方法从DOM中删除一个子节点

父节点.removeChild(要删除子节点);

节点不能主动删除自己,必须由父节点删除它

克隆节点

cloneNode()方法可以克隆节点,克隆出的节点是“孤儿节”

var 孤儿节点 = 老节点.cloneNode();
var 孤儿节点 = 老节点.cloneNode(true);

参数是一个布尔值,表示是否采用深度克隆:如果为true,则该节点的所有后代节点也都会被克隆,如果为false,则只克隆该节点本身

改变元素节点的CSS样式

改变元素节点的CSS样式需要使用这样的语句:

//css属性要写成“驼峰”形式
oBox.style.backgroundColor = 'red';
oBox.style.backgroundImage = 'url(images/1.jpg)";
oBox.style.fontSize = '32px';

改变元素节点的HTML属性

标准W3C属性,如src、href等等,只需要直接打点进行更改即可

oImg.src='images/2.jpg';

不符合W3C标准的属性,要使用setAttribute()和getAttribute()来设置、读取

oBox.setAttribute('data-n',10);

var n = oBox.getAttribute('data-n');
alert(n);

nodeType

节点的nodeType属性可以显示这个节点具体的类型

nodeType值节点类型
1元素节点,例如<p>和<div>
3文字节点
8注释节点
9document节点
10DTD节点

延迟运行

在测试DOM代码时,通常JS代码一定要写到HTML节点的后面,否则J5无法找到相应HTML节点

可以使用window.onload=function(){}事件,使页面加载完毕后,再执行指定的代码

节点的关系

父节点与子节点:第一个子节点firstChild,最后一个子节点lastChild,所有子节点childNodes
子节点与父节点:父节点parentNode
兄弟节点:上一个兄弟节点previousSibling,下一个兄弟节点nextSibling

DOM中,文本节点也属于节点,在使用节点的关系时一定要注意

在标准的W3C规范中,空白文本节点也应该算作节点,但是在IE8及以前的浏览器中会有一定的兼容问题,它们不把空文本节点当做节点

从IE9开始支持只考虑元素节点的属性

父节点与子节点:第一个子节点firstElementChild,最后一个子节点lastElementChild,所有子节点children
子节点与父节点:父节点parentNode
兄弟节点:上一个兄弟节点previousElementSibling,下一个兄弟节点nextElementSibling

DOM事件

常见的鼠标事件监听

事件名事件描述
onclick当鼠标单机某个对象
ondbclick当鼠标双击某个对象
onmousedown但某个鼠标按键在某个对象上被按下
onmouseup当某个鼠标按键在某个对象上被松开
onmousemove当某个鼠标按键在某个对象上被移动
onmouseenter当鼠标进去某个对象,与onmouseover相似
onmouseleave当鼠标离开某个对象,与onmouseout相似

常见的键盘事件监听

事件名事件描述
onkeypress当某个键盘的键被按下(系统按钮如箭头和功能键无法得到识别)
onkeydown当某个键盘的键被按下(系统按钮可以识别,并且会先于onkeypress发生)
onkeyup当某个键盘的键被松开

常见的表单事件监听

事件名事件描述
oninput当用户改变域的内容
onchange当用户改变域的内容,元素失去焦点才会改变
onfocus当某个元素获得焦点(比如tab键或鼠标点击)
onblur当某元素失去焦点
onsubmit当表单被提交
onreset当表单被重置

常见的页面事件监听

事件名事件描述
onload当页面或图像被完成加载
onunload当用户退出页面

事件传播

事件的传播是:先从外到内(捕获阶段 capturing phase),然后再从内到外(冒泡阶段 bubbling phase)。

onxxx写法的事件监听只能监听冒泡阶段,DOM0级的写法

addEventListener()方法,DOM2级的写法

oBox.addEventListener('click',function() {
    //事件处理
},true);//true监听捕获简短,false监听冒泡阶段

最内层的元素不论捕获或者冒泡,先写谁就先执行谁,所以最内层元素书写顺序会影响执行顺序

如果给元素设置相同的两个或多个同名事件,则DOM0级写法后面写的会覆盖先写的;而DOM2级会按顺序执行

事件对象

事件处理函数提供一个形式参数,它是一个对象,封装了本次事件的细节

这个参数通常用单词event或字母e来表示

oBox.onmousemove = function(e){
    // 对象e就是此次事件的事件对象
}

鼠标位置

属性属性描述
clientX鼠标指针相对于浏览器的水平坐标
clientY鼠标指针相对于浏览器的垂直坐标
pageX鼠标指针相对于整张网页的水平坐标
pageY鼠标指针相对于整张网页的垂直坐标
offsetX鼠标指针相对于事件源元素的水平坐标
offsetY鼠标指针相对于事件源元素的垂直坐标

e.charCode属性通常用于onkeypress事件中,表示用户输入的字符的“字符码”

e.keyCode属性通常用于onkeydown事件和onkeyup中,表示用户按下的按键的“键码”

charCode字符码

字符字符码
数字0 ~ 数字948 ~ 57
大写字母A ~ Z65 ~ 90
小写字母a ~ z97 ~ 122

keyCode键码

按键键码
数字0 ~ 数字948 ~ 57 同charCode键码完成相同
大写字母A ~ Z,小写字母a ~ z65 ~ 90 同charCode键码的大写字母,而keyCode不分大小写,一律为65 ~ 90
四个反向键 左上右下37、38、39、40
回车键13
空格键32

e.preventDefault()方法用来阻止事件产生的“默认动作”

一些特殊的业务需求,需要阻止事件的“默认动作”

鼠标滚轮事件是onmousewheel,它的事件对象e提供deltaY属性表示鼠标滚动方向,向下滚动时返回正值,向上滚动时返回负值

e.stopPropagation()方法用来阻止事件继续传播

在一些场合,非常有必要切断事件继续传播,否则会造成页面特效显示出bug

事件委托

利用事件冒泡机制,将后代元素事件委托给祖先元素

事件委托通常需要结合使用e.target属性

属性属性描述
target触发此事件的最早元素,即“事件源元素”
currentTarget事件处理程序附加到的元素

使用事件委托时需要注意的事项,不能委托不冒泡的事件给祖先元素,并且最内层元素不能再有额外的内层元素了

onmouseenter和onmouseover都表示“鼠标进入”,它们有什么区别呢?

答:onmouseenter不冒泡,onmouseover冒泡。

上次编辑于: 2022/11/4 17:16:44
贡献者: lanjd