Dom
Dom
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标志语言的标准编程接口 (API)。 (DOM 就是用来处理 HTML 机构)。
节点
加载 HTML 页面时,web 浏览器生成一个树型结构,用来表示页面内部结构,称之为 DOM 树,DOM 将这种树型结构理解为由节点组成。
节点属性
nodeType(节点类型) | nodeName(节点名称) | nodeValue(节点值) |
---|---|---|
1(元素节点) | 大写的标签名 | null |
3(文本节点) | #text | 文本内容 |
8(注释节点) | #comment | 注释内容 |
9(文档节点) | #document | null |
获取子节点
Tip:是属性,不是方法。
- 父亲节点.children; 获取直接元素子节点。注:即 nodeType==1 的元素节点。
- 父亲节点.childNodes; 获取直接子节点 (和结构相关结构边了这个集合也会改变:比如去掉空格或者换行就相当于去掉了文本节点 text)。
- 获取子节点,获取到了就是一个类数组集合,获取不到就是空集合。
1 | <ul id="ul1"> |
可以通过节点属性获取到想要的节点,比如 P 节点:
1 | <ul id="ul1"> |
获取父节点
Tip:是属性,不是方法。
- parentNode; 获取直接父节点 获取不到是 null。
- offsetParent; 获取已经定位的父集元素,如果说没有已经定位的父集元素获取到的就是 body。
- 获取到的还是一个元素节点,所以可以链式操作 =>test2.parentNode.parentNode。
- 获取到的是一个元素对象(具体的节点),获取不到就是 null。
1 | <div id="test"> |
节点的其他获取方式
- 带 Element 的就是元素节点;不带的就是节点 (基本都是文本节点 #text)
- firstElementChild: 获取第一个元素子节点(不兼容:IE8 及以下没有这个属性 ->undefined)
- firstChild:获取第一个子节点
- lastElementChild:获取最后一个元素子节点(不兼容:IE8 及以下没有这个属性 ->undefined)
- lastChild:获取最后一个子节点
- previousElementSibling:获取上一个相邻元素节点(不兼容:IE8 及以下没有这个属性 ->undefined)
- previousSibling:获取上一个相邻节点
- nextElementSibling:获取下一个相邻元素节点(不兼容:IE8 及以下没有这个属性 ->undefined)
- nextSibling:获取下一个相邻节点
节点的操作
节点的操作就包含了创建、添加、插入、替换、移除与克隆;
插入元素的方式如下:(可一下传入多个)
node.append (…nodes or strings)—— 在 node 下一级末尾插入节点或字符串;
node.prepend (…nodes or strings)—— 在 node 下一级开头插入节点或字符串;
node.before (…nodes or strings)—— 在 node 同级前面插入节点或字符串;
node.after (…nodes or strings)—— 在 node 同级后面插入节点或字符串;
node.replaceWith (…nodes or strings)—— 将 node 替换为给定的节点或字符串;
node.remove ()—— 将 node 移除;
node.cloneNode (boolean)—— 将 node 克隆;
- boolean 默认为 false,只会 clone 本身;
- boolean 设置为 true,深度克隆,子元素也会克隆;
添加:
1 | <div class="box"> |
1 | const box = document.getElementsByClassName("box")[0]; |
执行结果为:
1 | <div class="box"> |
旧的节点操作方法
在很多地方我们也会看到一些旧的操作方法:**(不推荐使用)**
- parentElem.appendChild (node):在 parentElem 的父元素最后位置添加一个子元素;
- parentElem.insertBefore (node, nextSibling):在 parentElem 的 nextSibling 前面插入一个子元素;
- parentElem.replaceChild (node, oldChild):在 parentElem 中,新元素替换之前的 oldChild 元素;
- parentElem.removeChild (node):在 parentElem 中,移除某一个元素;
操作元素结构上的属性
ps:color 属性是 style 里的呀,所以 style 里面的属性用的是 xxx.style.xxx;别的用的 Attribute;
attribute
- 标准的 attribute:某些 attribute 属性是标准的,比如 id、class、href、type、value 等;
- 非标准的 attribute:某些 attribute 属性是自定义的,比如 abc、age、height 等;
1 | <div id="myDiv" class="mydivClass" age="18" height="188"></div> |
对于所有的 attribute 访问都支持如下的方法:
- 元素对象.hasAttribute (attr);检查是否存在 返回 boolean 值;
- 元素对象.setAttribute (attr,val); 设置
- 元素对象. getAttribute (attr);获取
- 元素对象.removeAttribute (attr);移除
attribute 具备以下特征:
- 它们的名字是大小写不敏感的(id 与 ID 相同);
- 它们的值总是字符串类型的;
property
对象。属性的方式;
- 对于标准的 attribute,会在 DOM 对象上创建与其对应的 property 属性:
- 对于非标准的 attribute,为
undefined
: - 除非特别情况,大多数情况下,设置、获取 attribute,推荐使用 property 的方式:
1 | <div id="myDiv" class="mydivClass" age="18" height="188"></div> |
1 | const myDiv = document.getElementById('myDiv'); |
data-* 自定义属性
HTML5 的 data-* 自定义属性,那么它们也是可以在 dataset 属性中获取到的:
1 | <div id="myDiv" class="mydivClass" data-age="18" data-height="188"></div> |
1 | const myDiv = document.getElementById('myDiv'); |
JavaScript 动态修改样式
其实用到了 property,通过
.style
的方式来修改;(即:标签有标准的 attribute:style);
常规写法
JS 动态修改样式,要是修改的样式很多,用 JS 修改,后期不移维护;
1 | <div id="myDiv" class="mydivClass" age="18">fsllala</div> |
1 | /** |
className
通过 className 来动态修改样式,它会替换整个 class 中的字符串;
元素的 class attribute,对应的 property 并非叫 class,而是 className;
这是因为 JavaScript 早期是不允许使用 class 这种关键字来作为对象的属性,所以 DOM 规范使用了 className;
1 | <div id="myDiv" class="mydivClass" age="18">fsllala</div> |
1 | .active { |
1 | const myDiv = document.getElementById('myDiv'); |
执行完后,检查 dom 元素,可以看到原来的 class 被替换掉了;
1 | <div id="myDiv" class="active" age="18">fsllala</div> |
classList
同 className 替换 class 名相比,如果我们需要添加或者移除单个的 class,那么可以使用 classList 属性。
- elem.classList 是一个特殊的对象:
- elem.classList.add (class):添加一个类;
- elem.classList.remove (class):添加 / 移除类;
- elem.classList.toggle (class):如果类不存在就添加类,存在就移除它;
- elem.classList.contains (class):检查给定类,返回 true/false;
- classList 是可迭代对象,可以通过 for of 进行遍历;
将文章上方的 className 替换成 classList.add:
1 | const myDiv = document.getElementById('myDiv'); |
执行完后,检查 dom 元素,可以看到原来的 class 后面添加了新的 class 名为 active ;
1 | <div id="myDiv" class="mydivClass active" age="18">fsllala</div> |
getComputedStyle
如果我们需要读取样式:
对于内联样式,是可以通过 style.* 的方式读取到的;
对于 style、css 文件中的样式,是读取不到的;
这个时候,我们可以通过 getComputedStyle 的全局函数来实现:
1 | <div id="myDiv" class="active" age="18" style="font-weight: 900;">fsllala</div> |
1 | .active { |
1 | const myDiv = document.getElementById('myDiv'); |