Loading... ## DOM对象的定义 DOM(Document Object Model)是[W3C](https://www.chinaw3c.org/)国际组织的一套Web标准。它定义了访问HTML文档对象的一套属性、方法和事件。 使用JavaScript操作DOM时分为三个方面:DOM Core(DOM核心操作)、HTML-DOM、CSS-DOM,我们通过Web标准可以动态的增加、删除、修改页面中的节点数据,使交互更加方便。 ![DOM结构](https://www.jbea.cn/usr/uploads/2022/09/1710112079.png) ## 节点与节点间的关系 ***节点***可以理解为HTML文档中每个标签或者元素。在HTML中节点是这样规定的: * 整个文档是一个**文档节点**。 * 每个html标签是一个**元素节点**。 * 包含在html元素中的文本时**文本节点**。 * 每个html属性是一个**属性节点**。 * 注释属于**注释节点**。 **节点与节点之间的关系大致能够分为以下5中:** 1. **父节点(parent)**:元素的上一层的那个节点就是该元素的父节点,每个元素都有一个父节点。 2. **子节点(children)**:元素下面第一层的所有节点都是该元素的子节点,一个元素可以有 >=0个节点。 3. **同辈节点(sibling)**:同辈节点也叫兄弟节点,拥有相同的父节点的节点互为同辈节点。 4. **祖辈节点(ancestor)**:祖辈节点也叫祖先节点,元素的父节点以及父节点的父节点、一次类推都是该节点的先辈节点。 5. **后代节点(descendant)**:同理,一个节点的子节点、子节点的子节点、以此类推,都是该节点的后代节点。 **文档节点DOM树展示:** ![文档节点DOM树](https://www.jbea.cn/usr/uploads/2022/09/3482909735.png) ## 节点信息 所有的节点都会包含节点的某些信息的属性,常见属性有: * nodeName(节点名称) * 元素节点的标签名称 * 属性节点的属性名称 * 文本节点的nodeName永远是 #text * 文档节点的nodeName永远是 #document * nodeValue(节点值) * 文本节点包含的文本 * 属性节点的属性值 * 对文档节点和元素节点不可用 * nodeType(节点类型) | 节点类型 | nodeType值 | | --------------- | ----------------- | | Element (元素) | ELEMENT_NODE(1) | | Attr(属性) | ATTRIBUTE_NODE(2) | | Text (文本) | TEXT_NODE (3) | | Comment (注释) | COMMENT_NODE (8) | | Document (文档) | DOCUMENT_NODE(9) | **演示案例:** ```html <body> <!--创建一个无序列表 --> <ul> <li id="jbea">青鸟技术栈-博客</li> <li>口袋刷题小程序</li> <li>在线考试</li> <li>联系我们</li> </ul> </body> <script> //获取id名称为"jbea"的元素信息 var li = document.getElementById('jbea'); var type = li.nodeType, name = li.nodeName, value = li.nodeValue; console.log(type, name, value); //输出结果:1 'LI' null var li_child = li.firstChild; //使用指定节点中第一个子节点 【下一个知识点】 type = li_child.nodeType name = li_child.nodeName value = li_child.nodeValue; console.log(type, name, value); //输出结果:3 '#text' '青鸟技术栈-博客' </script> ``` ## 访问节点 **使用document.getElement系列方法访问指定节点:** 1. `getElementById()`:根据ID属性获取指定元素 2. `getElementsByName()`:根据Name属性值获取一组元素 3. `getElementsByTagName()`:根据标签名称获取一组元素 4. `getElementsByClassName()`:根据类样式名称获取一组数据 **根据层次关系访问节点:** **🟧 节点属性** | 属性名称 | 描述 | | --------------- | ---------------------------------------------------------- | | parentNode | 返回节点的父节点 | | childNodes | 返回子节点集合,childNodes[i] | | firstChild | 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 | | lastChild | 返回节点的最后一个子节点 | | nextSibling | 返回下一个节点 | | previousSibling | 返回上一个节点 | **案例演示:** ```html <body> <div id="content"> <h2>关于我们</h2> <ul> <li id="jbea">青鸟技术栈-博客</li> <li>口袋刷题小程序</li> <li>在线考试</li> <li>联系我们</li> </ul> </div> </body> <script> // A.如何获取id为content元素下所有的子元素? // 1. 先拿到id为content的元素 var node = document.getElementById("content"); // 2. 通过childNodes获取其子节点 var nodes = node.childNodes; // 3. 打印 console.log(nodes); //打印结果: NodeList(5) [text, h2, text, ul, text] //问题1:我们期望得到的是h2和ul元素,为什么这里得到了5个子元素呢? // B. 如何获取“联系我们”这个li节点?在上述代码基础上完成 var li = node.lastChild.lastChild; // --获取到ul --获取到ul中最后一个子节点 // 打印 console.log(li); //打印结果: null //问题2:我们期望得到的是“联系我们”的li元素,为什么这里打印为null? </script> ``` <div class="tip inlineBlock error simple"> **⚠️注意:** 在格式化文档所添加的**换行、回车、缩进**等字符构成**文本节点**,干扰节点访问,不推荐直接使用节点属性获取对应的节点信息。 👍👍👍推荐使用element属性获取节点数据。 </div> **🟩 element属性** | 属性名称 | 描述 | | ---------------------- | ---------------------------------------------------------- | | parentElement | 获取当前元素的父级元素 | | children | 获取当前元素的子元素,它返回一个 HTMLCollection 的集合 | | firstElementChild | 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 | | lastElementChild | 返回节点的最后一个子节点 | | nextElementSibling | 下一个节点 | | previousElementSibling | 上一个节点 | **案例演示:** ```html <body> <div id="content"> <h2>关于我们</h2> <ul> <li id="jbea">青鸟技术栈-博客</li> <li>口袋刷题小程序</li> <li>在线考试</li> <li>联系我们</li> </ul> </div> </body> <script> // A.如何获取id为content元素下所有的子元素? // 1. 先拿到id为content的元素 var node = document.getElementById("content"); // 2. 通过children属性获取指定节点下的子节点 var nodes = node.children; // 3. 打印 console.log(nodes); //打印结果: HTMLCollection(2) [h2, ul] //完美解决上一个案例中的问题1 // B. 如何获取“联系我们”这个li节点?在上述代码基础上完成 var li = node.lastElementChild.lastElementChild; // --获取到ul --获取到ul中最后一个子节点 // 打印 console.log(li); //打印结果: <li>联系我们</li> //完美解决上一个案例中的问题2 </script> ``` <div class="tip inlineBlock info simple"> **🙌经验分享:** 在实际开发中,为了保证浏览器的最佳兼容性,我们推荐使用如下书写形式 ```javascript var oNext = oParent.nextElementSibling || oParent.nextSibling; //获取下一个同辈节点 var oPre = oParent.previousElementSibling || oParent.previousSibling; //获取上一个同辈节点 var oFirst = oParent. firstElementChild || oParent.firstChild; //获取第一个子节点 var oLast = oParent.lastElementChild || oParent.lastChild; //获取最后一个子节点 ``` </div> ## 操作节点样式 在HTML页面中CSS使用非常频繁,我们可以通过JavaScript动态添加、修改、删除HTML文档中的样式信息,以达到页面的动态特效。 ### style属性 在JavaScript中,可以使用style属性设置html元素的样式信息,style是一个对象,表示一个单独的样式声明,可以通过应用样式的文档或者元素访问style对象,使用style对象设置样式的语法格式如下: `HTML-Element.style.样式属性 = "属性值";` <div class="tip inlineBlock warning simple"> **温馨提示:** 在css样式表中font-size表示字体大小,但是我们通过style属性设置字体大小时,我们需要将"-"删除,并且还需要将"-"后面的单词首字母修改为大写(驼峰命名法),例如:font-size → fontSize、background-color → backgroundColor... </div> <div class="tip inlineBlock error simple"> **⚠️注意:**使用style属性添加的样式将会以行内样式的形式出现在对应的html标签中。 </div> #### 常见样式属性 | 类别 | 属性 | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | 背景(background) | backgroundColor、backgroundImage、backgroundRepeat | | 文本(text) | font、fontSize、fontWeight、textAlign、textDecoration、color | | 边距(padding、margin) | padding、paddingTop 、paddingBottom、paddingLeft、paddingRight<br />margin、marginTop、marginBottom、marginLeft、marginRight | | 边框(border) | border、borderTop、borderBottom、borderLeft、borderRight | **演示案例:** ```html <body> <!-- 演示案例中省略样式代码 --> <section id="shopping"> <div id="cart" onmouseover="over()" onmouseout="out()">我的购物车<span>1</span></div> <div id="cartList"> <h2>最新加入的商品</h2> <ul> <li><img src="images/makeup.jpg"></li> <li>倩碧经典三部曲套装(液体皂800ml+明肌2号水800ml+润肤乳85ml)</li> <li>¥888.00×1<br/>删除</li> </ul> <div class="footer">共1件商品<span>共计¥888.00</span> <span>去购物车</span></div> </div> </section> </body> <script> //窗体加载完毕后执行脚本代码 window.onload = function(){ //获取购物车列表 var cartList = document.getElementById("cartList"); //将其默认显示为隐藏状态 cartList.style.display = "none"; //获取购物车元素为其绑定鼠标悬浮事件 var cart = document.getElementById("cart"); //绑定鼠标悬浮事件 cart.onmouseover = function(){ this.style.backgroundColor = "#fff"; this.style.zIndex = "100"; this.style.borderBottom = "none"; cartList.style.display = "block"; cartList.style.position = "relative"; cartList.style.top = "-1px"; } //绑定鼠标离开事件 cart.onmouseleave = function(){ this.style.backgroundColor = "#f9f9f9" this.style.zIndex = "100"; this.style.borderBottom = "1px solid #dcdcdc"; cartList.style.display = "none"; } //解决鼠标炫富至详细列表时,购物车列表隐藏的问题 cartList.onmouseover = function(){ cart.style.backgroundColor = "#fff"; cart.style.zIndex = "100"; cart.style.borderBottom = "none"; this.style.display = "block"; this.style.position = "relative"; this.style.top = "-1px"; } cartList.onmouseleave = function(){ cart.style.backgroundColor = "#f9f9f9" cart.style.zIndex = "100"; cart.style.borderBottom = "1px solid #dcdcdc"; this.style.display = "none"; } } </script> ``` **演示效果:** ![案例演示效果图](https://www.jbea.cn/usr/uploads/2022/09/3379173616.gif) **演示案例下载地址:** <div class="hideContent">此处内容需要评论回复后(审核通过)方可阅读。</div> ### className属性 在HTML DOM中,className属性可以设置或返回元素的class样式。 **语法:** `HTML-Element.className = "定义好的样式名称";` **演示案例** ```javascript //** html代码无任何变化 ** //窗体加载完毕后执行脚本代码 window.onload = function(){ //获取购物车列表 var cartList = document.getElementById("cartList"); //将其默认显示为隐藏状态 cartList.style.display = "none"; //获取购物车元素为其绑定鼠标悬浮事件 var cart = document.getElementById("cart"); //绑定鼠标悬浮事件 cart.onmouseover = function(){ //使用class属性设置时需要提前拥有对应的class样式 this.className = "cartOver"; cartList.className = "cartListOver"; } //绑定鼠标离开事件 cart.onmouseleave = function(){ //使用class属性设置时需要提前拥有对应的class样式 this.className = "cartOut"; cartList.className = "cartListOut"; } //解决鼠标炫富至详细列表时,购物车列表隐藏的问题 cartList.onmouseover = function(){ cart.className = "cartOver"; this.className = "cartListOver"; } cartList.onmouseleave = function(){ cart.className = "cartOut"; this.className = "cartListOut"; } } ``` ### 获取样式 在上面的文章中,我们讲解了如何给指定的html元素设定样式,那我们在开发过程中如何获取某个元素所拥有的样式信息呢?在JavaScript中提供了以下几种方式用于获取html元素的样式信息。 #### style属性 `HTML-Element.style.样式属性; `在之前的内容我们可以通过style属性设置样式,当然,我们也可以通过style属性获取指定样式属性的值。 #### getComputedStyle()方法 `document.defaultView.getComputedStyle(HTML-Element,null).属性; ` <div class="tip inlineBlock error simple"> **⚡警告:** getComputedStyle()方法在IE6、IE7、IE8中无法正常解析。 </div> #### currentStyle属性 `HTML-Element.currentStyle.样式属性;` 该属性为只读属性,只能用于获取指定元素的样式信息,不允许通过它对html元素修改样式。 <div class="tip inlineBlock error simple"> ⚡ **警告:仅支持IE5.0 或以后版本以及Opera浏览器!** </div> ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>青鸟技术栈</title> <style type="text/css"> .demo { font-weight: 900; } </style> </head> <body> <div style="color:red; font-size:18px;" class="demo" id="box">青鸟技术栈</div> </body> <script> //获取ID为box的元素 var box = document.getElementById("box"); //使用style属性获取对应的样式 var color = box.style.color; var font = box.style.fontWeight; //能否获得类class中的的样式? console.log(color, font); //打印结果:red //使用getComputedStyle()方法获取样式信息 color = document.defaultView.getComputedStyle(box).color; font = document.defaultView.getComputedStyle(box).fontWeight; //能否获得类class中的的样式? console.log(color, font); //打印结果:rgb(255, 0, 0) 900 //使用currentStyle属性获取样式信息 *由于没有IE浏览器,此处省略代码 /***************************优化上述代码**********************************/ /** * 获取样式 [兼容处理] * @param {any} element 对应的html元素 * @param {string} attr 需要获取的样式属性,例如:color、fontSize * @returns 样式属性值 */ function getStyle(element, attr) { return element.currentStyle ? element.currentStyle[attr] : getComputedStyle(element)[attr]; } color = getStyle(box,"color"); font = getStyle(box,"fontWeight"); console.log(color, font); //打印结果:rgb(255, 0, 0) 900 </script> </html> ``` --- <div class="tip inlineBlock info simple"> ▶️ 开始学习下一章: [JavaScript+Jquery+ES6入门到放弃之DOM应用](https://jbea.cn/archives/542.html) </div> 最后修改:2022 年 09 月 05 日 © 允许规范转载 赞 4 都滑到这里了,不点赞再走!?