DOM 文档对象模型

DOM是文档对象模型,用于操作网页。本文介绍了DOM的基本概念,包括文档节点、元素节点、文本节点和属性节点,以及如何通过document对象获取和操作这些节点。事件部分讨论了事件的绑定和传播机制,包括事件冒泡和事件委托。此外,还详细阐述了如何修改和读取元素的CSS样式。
摘要由CSDN通过智能技术生成

目录

一、简介

二、节点Node

三、document

1、简介

2、document对象的原型链

3、部分属性

四、元素节点

1、如何获取元素节点对象

通过document对象来获取已存在的元素节点

通过document对象来创建元素节点

2、原型链

3、通过元素节点对象获取其他节点的方法

五、文本节点

修改文本的三个属性

六、属性节点

操作属性节点

七、事件

绑定响应函数的方式:

八、文档加载

解决办法:

九、修改DOM

十、节点的复制

十一、修改元素的css样式

十二、读取元素的css样式(通用)

十三、通过属性读取元素的css样式

十四、修改class间接修改css样式

十五、事件对象

十六、Event对象

十七、事件冒泡

十八、事件委派

十九、事件的传播机制

二十、事件的捕获


一、简介

DOM,全称Document Object Model,中文翻译为文档对象模型。DOM属于Web API的一部分。Web API中定义了非常多的对象,通过这些对象可以完成对网页的各种操作(添加删除元素、发送请求、操作浏览器等)。

DOM中的D意为Document,即文档。所谓文档就是指整个网页,换言之,DOM是用来操作网页的。

O意为Object,即对象。DOM将网页中的每一部分内容都转换为了对象。转换对象以后,我们就可以以面向对象的方式去操作网页,想要操作哪个元素就获取哪个元素的对象,然后通过调用其方法或属性完成各种操作。

M意为Model,即模型。模型用来表示对象之间的关系。

<!DOCTYPE html>
<html lang="zh">
<head>
    <title>My Title</title>
</head>
<body>
    <h1>A Heading</h1>
    <a href="#">Link Text</a>
</body>
</html>

二、节点Node

在DOM标准下,网页中的每一个部分都会转换为对象。这些对象有一个共同的称呼——节点(Node)。一个页面将会由多个节点构成,虽然都称为节点,但是它们却有着不同的类型:

  1. 文档节点
  2. 元素节点
  3. 文本节点
  4. 属性节点

每一个节点都有其不同的作用,文档节点表示整个网页,元素节点表示某个标签,文本节点表示网页中的文本内容,属性节点表示标签中的各种属性。如果从对象的结构上来讲,这些对象都有一个共同的父类Node。总的来说,都是属于节点,但是具体类型不同。

关系:

  • 祖先 —— 包含后代元素的元素是祖先元素
  • 后代 —— 被祖先元素包含的元素是后代元素
  • 父 —— 直接包含子元素的元素是父元素
  • 子 —— 直接被父元素包含的元素是子元素
  • 兄弟 —— 拥有相同父元素的元素是兄弟元素

三、document

1、简介

要使用DOM来操作网页,我们需要浏览器至少得先给我一个对象,才能去完成各种操作。所以浏览器已经为我们提供了一个document对象,它是一个全局变量可以直接使用。

document代表的是整个的网页。比document大的是window。

2、document对象的原型链

HTMLDocument -> Document -> Node -> EventTarget -> Object.prototype -> null

凡是在原型链上存在的对象的属性和方法都可以通过Document去调用。

3、部分属性

document.documentElement --> html根元素

document.head --> head元素

document.title --> title元素

document.body --> body元素

document.linksimgs/forms... --> 获取页面中所有的超链接/图片/表单...

四、元素节点

在网页中,每一个标签都是一个元素节点

1、如何获取元素节点对象

通过document对象来获取已存在的元素节点

document.getElementById():根据id获取一个元素节点对象

document.getElementsByClassName():根据元素的class属性值获取一组元素节点对象,返回的是一个类数组对象。该方法返回的结果是一个实时更新的集合,当网页中新添加元素时,集合也会实时的刷新。

document.getElementsByTagName():根据标签名获取一组元素节点对象。返回的结果是可以实时更新的集合。document.getElementsByTagName("*") 获取页面中所有的元素。

document.getElementsByName():根据name属性获取一组元素节点对象。返回一个实时更新的集合。主要用于表单项

document.querySelectorAll():根据选择器去页面中查询元素。会返回一个类数组(不会实时更新)。

document.querySelector():根据选择器去页面中查询第一个符合条件的元素

通过document对象来创建元素节点

document.createElement():根据标签名创建一个元素节点对象。

2、原型链

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <div id="box1">
        </div>
    </body>
</html>

以上代码中div元素的原型链:HTMLDivElement(因元素的不同而不同) -> HTMLElement -> Element -> Node -> (与document一致) EventTarget -> Object.prototype -> null。

3、通过元素节点对象获取其他节点的方法

一些与document重复的方法:element.getElementById()element.getElementsByClassName()element.getElementsByTagName()

element.childNodes 获取当前元素的子节点(会包含空白的子节点)

element.children 获取当前元素的子元素

element.firstElementChild 获取当前元素的第一个子元素

element.lastElementChild 获取当前元素的最后一个子元素

element.nextElementSibling 获取当前元素的下一个兄弟元素

element.previousElementSibling 获取当前元素的前一个兄弟元素

element.parentNode 获取当前元素的父节点

element.tagName 获取当前元素的标签名

五、文本节点

在DOM中,网页中所有的文本内容都是文本节点对象, 可以通过元素来获取其中的文本节点对象,但是我们通常不会这么做。我们可以直接通过元素去修改其中的文本

修改文本的三个属性

element.textContent 获取或修改元素中的文本内容

                                - 获取的是标签中的内容,不会考虑css样式

element.innerText 获取或修改元素中的文本内容

                                - innerText获取内容时,会考虑css样式

                                - 通过innerText去读取CSS样式,会触发网页的重排(计算CSS样式)

                                - 当字符串中有标签时,会自动对标签进行转义,将标签作为文本

                                - <li> --> &lt;li&gt;

element.innerHTML 获取或修改元素中的html代码

                                - 可以直接向元素中添加html代码

                                - innerHTML插入内容时,有被xss注入的风险

<div id="box1">
     <span>我是box1</span>
</div>

六、属性节点

在DOM也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作

操作属性节点

方式一:

读取:元素.属性名(注意,class属性需要使用className来读取)。读取一个布尔值时,会返回true或false,如disabled属性

<input class="a" type="text" name="username" value="admin">




const input = document.getElementsByName("username")[0]

const input = document.querySelector("[name=username]")

修改:元素.属性名 = 属性值

方式二:

读取:元素.getAttribute(属性名)

修改:元素.setAttribute(属性名, 属性值)

删除:元素.removeAttribute(属性名)

七、事件

事件就是用户和页面之间发生的交互行为,比如:点击按钮、鼠标移动、双击按钮、敲击键盘、松开按键...

可以通过为事件绑定响应函数(回调函数),来完成和用户之间的交互。

绑定响应函数的方式:

   1.可以直接在元素的属性中设置

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <button id="btn" onmouseenter="alert('你点我干嘛~')">点我一下</button> 
        
        </script>
    </body>
</html>

  2.可以通过为元素的指定属性设置回调函数的形式来绑定事件(一个事件只能绑定一个响应函数)

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <button id="btn">点我一下</button>

        <script>
          
            // 获取到按钮对象
            const btn = document.getElementById("btn")
            // 为按钮对象的事件属性设置响应函数
            btn.onclick = function(){
                 alert("我又被点了一下~~")
            }

        </script>
    </body>
</html>

 3.可以通过元素addEventListener()方法来绑定事件

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <button id="btn">点我一下</button>

        <script>
          
            // 获取到按钮对象
            const btn = document.getElementById("btn")
            
            // 给对象绑定监听事件
            btn.addEventListener("click", function(){
                alert("哈哈哈")
            })

       
        </script>
    </body>
</html>

八、文档加载

网页是自上向下加载的,如果将js代码编写到网页的上边,js代码在执行时,网页还没有加载完毕,这时会出现无法获取到DOM对象的情况。

解决办法:

1、将script标签编写到body的最后

如果script标签鞋到了body外面,也会自动把它放进body里面

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <button id="btn">点我一下</button>

        <script>
            const btn = document.getElementById("btn")
            console.log(btn)
        </script>
    </body>
</html>

2、将代码编写到window.onload的回调函数中

window.onload 事件会在窗口中的内容加载完毕之后才触发。窗口不止一个文档。

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script>
           
            window.onload = function () {
                const btn = document.getElementById("btn")
                console.log(btn)
            }
         
        </script>   
    </head>
    <body>
        <button id="btn">点我一下</button>
    </body>
</html>

3、 将代码编写到document对象的DOMContentLoaded的回调函数中(执行时机更早)

document的DOMContentLoaded事件会在当前文档加载完毕之后触发

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script>
            document.addEventListener("DOMContentLoaded", function () {
                 const btn = document.getElementById("btn")
                 alert(btn)
            })
        </script>
    </head>
    <body>
        <button id="btn">点我一下</button>
    </body>
</html>

4、将代码编写到外部的js文件中,然后以defer的形式进行引入(执行时机更早,早于DOMContentLoaded)

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script defer src="./script/script.js"></script>
    </head>
    <body>
    </body>
</html>

5、将代码编写到外部的js文件中,然后以async的形式进行引入(执行时机更早,早于DOMContentLoaded)

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script async src="./script/script.js"></script>
    </head>
    <body>
    </body>
</html>

九、修改DOM

1、appendChild() :用于给一个节点添加子节点

2、insertAdjacentElement(要添加的位置,要添加的元素):可以向元素的任意位置添加元素

要添加的位置=beforeend 标签的最后 ;afterbegin 标签的开始  ;beforebegin 在元素的前边插入元素(兄弟元素); afterend 在元素的后边插入元素(兄弟元素)

list.insertAdjacentHTML("beforeend", "<li id='bgj'>白骨精</li>")

3、元素1.replaceWith(元素2) :使用一个元素替换当前元素

// 获取swk
const swk = document.getElementById("swk")

swk.replaceWith(li)

4、元素.remove():方法用来删除当前元素

const swk = document.getElementById("swk")

swk.remove()

十、节点的复制

节点.cloneNode()

使用 cloneNode() 方法对节点进行复制时,它会复制节点的所有特点包括各种属性。这个方法默认只会复制当前节点,而不会复制节点的子节点。可以传递一个true作为参数,这样该方法也会将元素的子节点一起复制。

十一、修改元素的css样式

元素.style.样式名 = 样式值

如果样式名中含有-,则需要将样式表修改为驼峰命名法。如果样式中有!important,再用上面的语法修改就改不了了

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            .box1 {
                width: 200px;
                height: 200px;
                background-color: #bfa;
            }
        </style>
    </head>
    <body>
        <button id="btn">点我一下</button>
        <hr />
        <div class="box1"></div>

        <script>
            // 点击按钮后,修改box1的宽度

            const btn = document.getElementById("btn")
            const box1 = document.querySelector(".box1")

            btn.onclick = function () {
                box1.style.width = "400px"
                box1.style.height = "400px"
                box1.style.backgroundColor = "yellow" // 如果样式名中含有-,则需要将样式表修改为驼峰命名法
            }
        </script>
    </body>
</html>

十二、读取元素的css样式(通用)

getComputedStyle(要获取样式的对象,要获取的伪元素):它会返回一个对象,这个对象中包含了当前元素所有的生效的样式。

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            .box1 {
                height: 200px;
                background-color: #bfa;
            }

            .box1::before {
                content: "hello";
                color: red;
            }
        </style>
    </head>
    <body>
        <button id="btn">点我一下</button>

        <hr />

        <div class="box1"></div>

        <script>
            /* 
                点击按钮后,读取元素的css样式
            */

            const btn = document.getElementById("btn")
            const box1 = document.querySelector(".box1")

            btn.onclick = function () {
                
                const styleObj = getComputedStyle(box1)

                console.log(styleObj.width)  // 输出某个元素的样式
                console.log(styleObj.left)

                const beforeStyle = getComputedStyle(box1, "::before")   // 获取伪元素的样式

                console.log(box1.firstElementChild)
            }
        </script>
    </body>
</html>

注意:样式对象中返回的样式值,不一定能来拿来直接计算。所以使用时,一定要确保值是可以计算的才去计算。

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            .box1 {
                height: 200px;
                background-color: #bfa;
            }

            .box1::before {
                content: "hello";
                color: red;
            }
        </style>
    </head>
    <body>
        <button id="btn">点我一下</button>

        <hr />

        <div class="box1"></div>

        <script>
            /* 
                点击按钮后,读取元素的css样式
            */

            const btn = document.getElementById("btn")
            const box1 = document.querySelector(".box1")

            btn.onclick = function () {
                const styleObj = getComputedStyle(box1)

                console.log(styleObj.width)
                console.log(styleObj.left)

                console.log(parseInt(styleObj.width) + 100)  // 将样式转换为字符串才可以进行计算
                box1.style.width = parseInt(styleObj.width) + 100 + "px"  // 使用、设置时要加上单位
            }
        </script>
    </body>
</html>

十三、通过属性读取元素的css样式

元素.clientHeight

元素.clientWidth

                   - 获取元素内部的宽度和高度(包括内容区和内边距)

元素.offsetHeight

元素.offsetWidth

                    - 获取元素的可见框的大小(包括内容区、内边距和边框)

元素.scrollHeight

元素.scrollWidth

                    - 获取元素滚动区域的大小

元素.offsetParent

                    - 获取元素的定位父元素

                    - 定位父元素:离当前元素最近的开启了定位的祖先元素,

                        如果所有的元素都没有开启定位则返回body

元素.offsetTop

元素.offsetLeft

                    - 获取元素相对于其定位父元素的偏移量

元素.scrollTop

元素.scrollLeft

                    - 获取或设置元素滚动条的偏移量

十四、修改class间接修改css样式

通过class修改样式的好处:

                        1. 可以一次性修改多个样式

                        2. 对JS和CSS进行解耦

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            .box1 {
                width: 200px;
                height: 200px;
                background-color: #bfa;
            }


            .box2{
                background-color: yellow;
                width: 300px;
                height: 500px;
                border: 10px greenyellow solid;
            }
        </style>
    </head>
    <body>
        <button id="btn">点我一下</button>

        <hr />

        <div class="box1 box3 box4"></div>

        <script>
            /* 
                点击按钮后,修改box1的宽度
            */

            const btn = document.getElementById("btn")
            const box1 = document.querySelector(".box1")

            btn.onclick = function () {
                     box1.className += " box2"

            }
        </script>
    </body>
</html>

元素.classList 是一个对象,对象中提供了对当前元素的类的各种操作方法

元素.classList.add() 向元素中添加一个或多个class

元素.classList.remove() 移除元素中的一个或多个class

元素.classList.toggle() 切换元素中的class

元素.classList.replace() 替换class

元素.classList.contains() 检查class

十五、事件对象

事件对象是有浏览器在事件触发时所创建的对象,这个对象中封装了事件相关的各种信息。通过事件对象可以获取到事件的详细信息,比如:鼠标的坐标、键盘的按键...浏览器在创建事件对象后,会将事件对象作为响应函数的参数传递,所以我们可以在事件的回调函数中定义一个形参来接收事件对象。

十六、Event对象

在DOM中存在着多种不同类型的事件对象,多种事件对象有一个共同的祖先 Event。

event.target :触发事件的对象

event.currentTarget :绑定事件的对象(同this)

event.stopPropagation() :停止事件的传导

event.preventDefault() :取消默认行为

十七、事件冒泡

事件的冒泡就是指事件的向上传到,当元素上的某个事件被触发后,其祖先元素上的相同事件也会同时被触发,冒泡的存在大大的简化了代码的编写,但是在一些场景下我们并不希望冒泡存在。不希望事件冒泡时,可以通过事件对象来取消冒泡

事件的冒泡和元素的样式无关,只和结构相关

十八、事件委派

希望只绑定一次事件,既可以让所有的超链接,包括当前的和未来新建的超链接都具有这些事件。

思路:可以将事件统一绑定给document,这样点击超链接时由于事件的冒泡, 会导致document上的点击事件被触发,这样只绑定一次,所有的超链接都会具有这些事件。

委派就是将本该绑定给多个元素的事件,统一绑定给document,这样可以降低代码复杂度方便维护。

十九、事件的传播机制

在DOM中,事件的传播可以分为三个阶段:

                        1.捕获阶段 (由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)

                        2.目标阶段 (触发事件的对象)

                        3.冒泡阶段 (由目标元素向祖先元素进行事件的冒泡)

二十、事件的捕获

指事件从外向内的传导,当前元素触发事件以后,会先从当前元素最大的祖先元素开始向当前元素进行事件的捕获。

如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true。一般情况下我们不希望事件在捕获阶段触发,所有通常都不需要设置第三个参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值