51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

JavaScript - DOM&BOM

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


什么是DOM {#%E4%BB%80%E4%B9%88%E6%98%AFdom}

DOM中的D意为Document,即文档。所谓文档就是指整个网页,换言之,DOM是用来操作网页的。O意为Object,即对象。DOM将网页中的每一部分内容都转换为了对象,div有div的对象,input有input的对象,甚至一段文本,一段注释也有其所对应的对象。转换为对象干什么?还记得面向对象吗?转换对象以后,我们就可以以面向对象的方式去操作网页,想要操作哪个元素就获取哪个元素的对象,然后通过调用其方法或属性完成各种操作。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>

dom-items.webp

>概念 {#%3E%E6%A6%82%E5%BF%B5}

节点(Node) {#%E8%8A%82%E7%82%B9%EF%BC%88node%EF%BC%89}

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

  1. 文档节点

  2. 元素节点

  3. 文本节点

  4. 属性节点

  5. ...

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

关系 {#%E5%85%B3%E7%B3%BB}

  • 祖先 ------ 包含后代元素的元素是祖先元素

  • 后代 ------ 被祖先元素包含的元素是后代元素

  • 父 ------ 直接包含子元素的元素是父元素

  • 子 ------ 直接被父元素包含的元素是子元素

  • 兄弟 ------ 拥有相同父元素的元素是兄弟元素

小试牛刀 {#%E5%B0%8F%E8%AF%95%E7%89%9B%E5%88%80}

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

<button id="btn">点我一下</button>

\<script\>
// 获取btn对象
const btn = document.getElementById("btn")

`// 修改btn中的文字
btn.innerText = "Click ME"
</script>`


>文档节点(document) {#%3E%E6%96%87%E6%A1%A3%E8%8A%82%E7%82%B9%EF%BC%88document%EF%BC%89}

  • document对象表示的是整个网页

  • document对象的原型链

HTMLDocument -> Document -> Node -> EventTarget -> Object.prototype -> null
  • 凡是在原型链上存在的对象的属性和方法都可以通过Document去调用

  • 部分属性:

document.documentElement --> html根元素
document.head --> head元素
document.title --> title元素
document.body --> body元素
document.links --> 获取页面中所有的超链接
...

>元素节点(element) {#%3E%E5%85%83%E7%B4%A0%E8%8A%82%E7%82%B9%EF%BC%88element%EF%BC%89}

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

如何获取元素节点对象?

  1. 通过document对象来获取元素节点

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

通过document来获取已有的元素节点:

document.getElementById() {#document.getelementbyid()}

  • 根据id获取一个元素节点对象
<button id="btn">点我一下</button>
<script>
const btn = document.getElementById("btn")
console.log(btn)
</script>

document.getElementsByClassName() {#document.getelementsbyclassname()}

  • 根据元素的class属性值获取一组元素节点对象
<span class="s1">我是span</span>
<span class="s1">我是span</span>
<span class="s1">我是span</span>
<span class="s1">我是span</span>
<span class="s1">我是span</span>

\<script\>


// 返回的是一个类数组对象,该方法返回的结果是一个实时更新的集合
// 当网页中新添加元素时,集合也会实时的刷新。


const spans = document.getElementsByClassName("s1")


console.log(spans) // HTMLCollection(5) \[span.s1, span.s1, span.s1, span.s1, span.s1\]


for (let i = 0; i \< spans.length; i++) {
spans\[i\].innerText = "我是span"+i
}

`</script>`

document.getElementsByTagName() {#document.getelementsbytagname()}

  • 根据标签名获取一组元素节点对象
<div>我是div</div>
<div>我是div</div>
<div>我是div</div>
<div>我是div</div>
<div>我是div</div>

\<script\>


// 返回的结果是可以实时更新的集合
const divs = document.getElementsByTagName("div")


// document.getElementsByTagName("") 获取页面中所有的元素
const divs = document.getElementsByTagName("")

`console.log(divs) // HTMLCollection(5) [div, div, div, div, div]
</script>`

document.getElementsByName() {#document.getelementsbyname()}

  • 根据name属性获取一组元素节点对象
<form>
    <input type="text" name="username">
    <input type="radio" name="gender" value="male"> 男
    <input type="radio" name="gender" value="female"> 女
</form>

\<script\>


// 返回一个实时更新的集合,主要用于表单项。
const genderInput = document.getElementsByName("gender")

`console.log(genderInput) // NodeList(2) [input, input]
</script>`

document.querySelectorAll() {#document.queryselectorall()}

  • 根据选择器去页面中查询元素
<div>我是div</div>
<div>我是div</div>
<div>我是div</div>

\<script\>


// 会返回一个类数组(不会实时更新)
const divs2 = document.querySelectorAll("div")

`console.log(divs2) // NodeList(3) [input, input,input]
</script>`

document.querySelector() {#document.queryselector()}

  • 根据选择器去页面中查询第一个符合条件的元素
<div>我是div</div>
<div>我是div</div>

\<script\>


// 会返回一个类数组(不会实时更新)
const div = document.querySelector("div") // .xx \| #xx


console.log(divs2) // NodeList(2) \[input,input\]

`</script>`

创建一个元素节点

document.createElement() {#document.createelement()}

  • 根据标签名创建一个元素节点对象
const h2 = document.createElement("h2") // 创建了H2,但未添加

>元素的属性和方法 {#%3E%E5%85%83%E7%B4%A0%E7%9A%84%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95}

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

\<script\>


const box1 = document.getElementById("box1")


cosole.log(box1.proto)

`</script>`

  • div的原型链
HTMLDivElement -> HTMLElement -> Element -> Node -> ...

element.childNodes {#element.childnodes}

  • 获取当前元素的子节点(会包含空白的子节点)
<div id="box1">
    我是box1
    <span class="s1">我是s1</span>
    <span class="s1">我是s1</span>
</div>

\<script\>


const box1 = document.getElementById("box1")


const cns = box1.childNodes


console.log(children.length) // 输出:5 包含空格

`</script>`

element.children {#element.children}

  • 获取当前元素的子元素
<div id="box1">
    我是box1
    <span class="s1">我是s1</span>
    <span class="s1">我是s1</span>
</div>

\<script\>


const box1 = document.getElementById("box1")


const children = box1.children


console.log(children.length) // 输出:2(2个span)

`</script>`

element.firstElementChild {#element.firstelementchild}

  • 获取当前元素的第一个子元素
<p>Hello world! This is HTML5 Boilerplate.</p>
<div id="box1">
    我是box1
    <span class="s1">我是s1</span>
    <span class="s1">我是s1-2</span>
</div>
    <h1>hello,world</h1>

\<script\>


const box1 = document.getElementById("box1")


console.log(box1.firstElementChild) //输出: \<span class="s1"\>我是s1\</span\>

`</script>`

element.lastElementChild {#element.lastelementchild}

  • 获取当前元素的最后一个子元素
console.log(box1.lastElementChild) //输出: <span class="s1">我是s1-2</span>

element.nextElementSibling {#element.nextelementsibling}

  • 获取当前元素的下一个兄弟元素
console.log(box1.nextElementSibling) //输出: <h1>hello,world</h1>

element.previousElementSibling {#element.previouselementsibling}

  • 获取当前元素的前一个兄弟元素
console.log(box1.previousElementSibling) //输出: <p>Hello world! This is HTML5 Boilerplate.</p>

element.parentNode {#element.parentnode}

  • 获取当前元素的父节点
console.log(box1.parentNode) //输出: <body>...</body>

element.tagName {#element.tagname}

  • 获取当前元素的标签名
console.log(box1.tagName) //输出: DIV

>文本节点(Text) {#%3E%E6%96%87%E6%9C%AC%E8%8A%82%E7%82%B9%EF%BC%88text%EF%BC%89}

在DOM中,网页中所有的文本内容都是文本节点对象。

可以通过元素来获取其中的文本节点对象,但是我们通常不会这么做。

我们可以直接通过元素去修改其中的文本

修改文本的三个属性

element.textContent {#element.textcontent}

  • 获取或修改元素中的文本内容
<div id="box1">
    <span style="text-transform: uppercase;">我是box1</span>
</div>

\<script\>


// 获取的是标签中的内容,不会考虑css样式
const box1 = document.getElementById("box1")


box1.textContent = "新的内容"

`</script>`

element.innerText {#element.innertext}

  • 获取或修改元素中的文本内容
<script>

// innerText获取内容时,会考虑css样式
// 通过innerText去读取CSS样式,会触发网页的重排(计算CSS样式)
const box1 = document.getElementById("box1")


box1.innerText = "新的内容"


// 当字符串中有标签时,会自动对标签进行转义
box1.innerText = "\<li\>我是li\</\>" //  \<li\> --\> \&lt;li\&gt;

`</script>`

element.innerHTML {#element.innerhtml}

  • 获取或修改元素中的html代码
<script>

// 可以直接向元素中添加html代码
const box1 = document.getElementById("box1")


box1.innerHTML = "XXX"

`// innerHTML插入内容时,有被xss注入的风险
box1.innerHTML = "<、script src='https://sss/sss.js'></script>"
</script>`

>属性节点(Attr) {#%3E%E5%B1%9E%E6%80%A7%E8%8A%82%E7%82%B9%EF%BC%88attr%EF%BC%89}

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

如何操作属性节点:

方式一 {#%E6%96%B9%E5%BC%8F%E4%B8%80}

  • 读取:元素.属性名(class属性需要使用 className 来读取)

读取一个布尔值时,会返回 true 或 false (如 disabled)

  • 修改:元素.属性名 = 属性名
 <input disabled="disabled" type="text" name="username" value="admin">

\<script\>


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


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


console.log(input) // console.log(input.type)


input.name = "biu" // 修改:元素.属性名 = 属性名

`</script>`

方式二 {#%E6%96%B9%E5%BC%8F%E4%BA%8C}

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

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

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

 <input disabled="disabled" type="text" name="username" value="admin">

\<script\>


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


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


input.getAttribute("name") // 读取:元素.getAttribute(属性名)


input.setAttribute("name","大王") // 修改:元素.setAttribute(属性名, 属性值)
input.setAttribute("disabled",true)


input.removeAttribute("disabled") // 删除:元素.removeAttribute(属性名)

`</script>`

事件(Event) {#%E4%BA%8B%E4%BB%B6%EF%BC%88event%EF%BC%89}

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

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

绑定响应函数的方式: {#%E7%BB%91%E5%AE%9A%E5%93%8D%E5%BA%94%E5%87%BD%E6%95%B0%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%9A}

  • 直接在元素的属性中设置
<button id="btn" onclick="alert('你点我干嘛~')">点我一下</button>
  • 为元素指定属性设置(回调函数)来绑定事件 (一个事件只能绑定一个响应函数)
<script>
// 获取到按钮对象
const btn = document.getElementById("btn")
// 为按钮对象的事件属性设置响应函数
btn.onclick = function(){
  alert("你点我干嘛~")
}
</script>
  • 可以通过元素 addEventListener( )方法来绑定事件 (可绑定多个,会依次执行)
<script>
// 通过元素 addEventListener( )方法来绑定事件
btn.addEventListener("click", function(){
  alert("哈哈哈哈~")
})
</script>

赞(0)
未经允许不得转载:工具盒子 » JavaScript - DOM&BOM