JavaScript DOM

本文深入讲解了DOM(Document Object Model)的概念及应用,包括如何利用JavaScript获取和操作页面元素,如元素的增删改查、属性、样式等,以及节点操作、元素偏移量和尺寸的获取方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaScript DOM


了解DOM

  • DOM(Document Object Model)文档对象模型,是一套操作文档流的属性和方法(API)
  • BOM就是对页面上的所有节点进行操作:元素的增删改查、元素的属性、元素的样式 …
  • DOM 就是由 document -> html -> head / body -> 其他元素(组成的一个树状结构)
  • S是被html文件引入,运行在浏览器里面
    • html 给我们提供了 DOM
    • 浏览器 给我们提供了 BOM
    • JS 提供了 语法
    • 它们三个在一起组成了一个完整的 JavaScript

获取页面中元素的方法

  • 作用:通过各种方式获取页面中的元素,比如:id、类名、标签名、选择器等方式来获取元素

  • 伪数组:
    • 长得和数组差不多,也是按照索引排列
    • 也有 length 属性,也可以使用 for 循环来遍历
    • 但是就是不能使用数组的常用方法
一、通过 id 获取元素的方法
  • 语法:document.getElementById(‘你要获取的元素的 id’)

  • 返回值:是 DOM 元素,也叫做 DOM 对象

    • 如果页面上有对应的 id 元素,那么就是这个元素
    • 如果页面上没有对应的 id 元素,那么就是 null
二、通过 类名 获取元素的方法
  • 语法:document.getElementsByClassName(‘你要获取的元素的类名’)

  • 返回值:是一个伪数组,伪数组里面包含着所有能获取到的元素

    • 页面上有多少类名符合的元素,那么这个伪数组里面就有多少个元素
    • 页面上没有类名符合的元素,那么就是一个空的伪数组
三、通过 标签名 获取元素的方法
  • 语法:document.getElementsByTagName(‘你要获取的元素的标签名’)

  • 返回值:是一个伪数组,伪数组里面包含所有能获取到的匀速

    • 页面上有多少标签名符合的元素,那么这个伪数组里面就有多少个元素
    • 页面上没有标签名符合的元素,那么就是一个空的伪数组
四、通过 选择器 获取一个元素的方法
  • 语法:document.querySelector(‘你要获取的元素的选择器’)

    • 选择器 => 你 css 怎么捕获这个元素的,那么这里就怎么写
  • 返回值:满足选择器的第一个元素

    • 如果页面上有满足选择器的元素,那么返回第一个满足条件的元素
    • 如果页面上没有满足选择器的元素,那么就是 null
五、通过 选择器 获取一组元素的方法
  • 语法:document.querySelectorAll(‘你要获取的元素的选择器’)

  • 返回值:一个伪数组

    • 如果页面上有满足选择器的元素,有多少满足,伪数组里面就有多少个
    • 如果页面上没有满足选择器的元素,那么就是空的伪数组
  • 注:有且仅有 querySelectAll 拿到的类数组可以用 forEach循环

六、案例
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="abc">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
  </div>

  <script>
    // 1. 通过 id 获取元素
    var box = document.getElementById('abc')
    console.log(box)
    var box = document.getElementById('a')
    console.log(box)

    // 2. 通过 类名 获取元素
    // 获取页面中所有类名为 box 的元素
    var boxs = document.getElementsByClassName('box')
    console.log(boxs)
    console.log(boxs[0])
    console.log(boxs[1])
    console.log(boxs[2])
    console.log(boxs[3])

    // 3. 通过 标签名 获取元素
    // 通过 div 这个标签名获取页面上的元素
    var divs = document.getElementsByTagName('div')
    console.log(divs)
    console.log(divs[0])
    console.log(divs[1])
    console.log(divs[2])
    console.log(divs[3])

    // 4. 通过 选择器 获取一个元素
    var div = document.querySelector('.box:last-child')
    console.log(div)

    // 5. 通过 选择器 获取一组元素
    // 获取页面上所有类名为 box 的元素
    var divs = document.querySelectorAll('.box')
    console.log(divs)
    console.log(divs[0])
    console.log(divs[1])
    console.log(divs[2])
    console.log(divs[3])
  </script>
</body>
</html>

  • 注:除了通过 id 获取元素,其他的方法获取元素获取到的都是伪数组

操作元素的属性 - 文本属性

  • 我们获取到的 DOM 元素,本身也是一个对象,其实就是操作这个 DOM 元素的某一个成员内容
一、innerHTML
  • 是一个读写的属性

  • 读:获取一个元素的所有后代元素内容,包含 html 结构

    • 你得到的是一个字符串
    • 语法:元素.innerHTML
  • 写:设置这个元素的内容部分,会完全覆盖式的写入

    • 语法:元素.innerHTML = '你要写的内容’
    • 特点:你写入的时候,如果写入一个 html 格式的字符串,它能解析出来
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="box">
    我是 div 下的文本内容
    <p>我是 div 下面的 p</p>
    <span>我是 div 下面的 span</span>
    <p>
      <em>我是 div 下面的 p 下面的 em 标签</em>
    </p>
  </div>

  <script>
    // 获取元素
    // 你获取到的是一个 包含 p 标签和 span 标签的 div
    var div = document.querySelector('#box')

    // innerHTML
    // 获取这个 div 标签里面的所有内容, 以字符串的形式
    console.log(div.innerHTML) 
    // 使用 innerHTML 属性来写入内容
    // 不是把内容写在页面上
    // 是把内容写在了 div 这个元素里面
    // 因为 div 这个元素在 页面上, 所以这些内容就在页面上了
    
    div.innerHTML = '<i class="a">我要写入一些内容</i>'
  </script>
</body>
</html>
二、innerText
  • 是一个读写的属性

  • 读:获取一个元素内所有的文本内容,包含后代元素的文本内容

    • 不包含 html 结构,是一个字符串
    • 语法:元素.innerText
  • 写:设置这个元素的内容部分,完全覆盖式的写入

    • 语法:元素.innerText = '你要写入的内容’
    • 特点:你写入的时候, 如果写入一个 html 格式的字符串, 他不会解析
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="box">
    我是 div 下的文本内容
    <p>我是 div 下面的 p</p>
    <span>我是 div 下面的 span</span>
    <p>
      <em>我是 div 下面的 p 下面的 em 标签</em>
    </p>
  </div>

  <script>
    // 获取元素
    // 你获取到的是一个 包含 p 标签和 span 标签的 div
    var div = document.querySelector('#box')

    // innerText
    // 获取这个 div 标签里面的所有文本, 以字符串的形式
    console.log(div.innerText) 
   
   // 使用 innerText 属性来写入内容
    div.innerText = '<em>我是新写入的内容</em>'
  </script>
</body>
</html>

三、value
  • 是一个读写的属性,专门用来和表单元素合作的

  • 读:获取一个标签元素的 value 属性的值

    • 语法:表单元素.value
  • 写:给一个表单元素设置 value 属性的值,完全覆盖式的写入

    • 语法:表单元素.value = '你要写入的内容’
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <input type="text" value="默认显示的内容">

  <script>
    // 获取元素
    var inp = document.querySelector('input')

    // value
    console.log(inp.value) // 默认显示的内容
    
    // 使用 value 属性来给表单元素写入一些内容
    inp.value = '我是新写入的内容'
    console.log(inp.value) // 我是新写入的内容
  </script>
</body>
</html>


操作元素的属性 - 原生属性

一、原生属性:元素自己本身就带有的属性
  • 每个元素都有的 id 属性

  • img 标签有的 type 属性

  • input 标签有的 type 属性

  • table 标签有的 border 属性

二、特别说明:class 属性不行(不可以操作元素属性)
三、原生属性直接操作就可以了
  • 读:元素.你要读取的属性名

  • 写:元素.你要写入的属性名 = '你要写入的值’

  • 案例1:操作原生属性 id 属性
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #box {
      background-color: skyblue;
      width: 100px;
      height: 100px;
    }
  </style>
</head>
<body>
  <div>我是一个 div</div>
  <script>
    // 操作原生属性 id 属性
    // 获取元素
    var div = document.querySelector('div')
    
    // // 设置 id 属性的值
    console.log(div.id) // 先获取一下看看
    div.id = 'box' // 把 div 元素的 id 名称设置为 box
  </script>
</body>
</html>
  • 案例2:操作原生属性 src 属性
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <img src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg" alt="">
  <script>
    // 操作原生属性 src 属性
    // 获取元素
    var img = document.querySelector('img')
    
    // 设置 src 属性
    console.log(img.src) // 先获取一下看看
    // 给 img 标签的 src 属性换一个地址
    img.src = 'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg'
  </script>
</body>
</html>
  • 案例3:操作原生属性 type 属性
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <input type="text" value="hello world">
  <script>
    // 操作原生属性 type 属性
    // 获取元素
    // inp 这个变量代表着 input 这个元素
    var inp = document.querySelector('input')
    
    // 设置 type 属性
    console.log(inp.type) // 先打印看一下 text
    inp.type = 'password' // 把这个 input 元素的 type 属性设置为 password
  </script>
</body>
</html>


操作元素属性 - 自定义属性

  • 自定义属性:元素本身不带有的属性,是我们自己定义的属性(我们想在元素身上写上这些属性)
一、setAttribute( )
  • 作用:给元素设置一个自定义属性

  • 语法:元素.setAttribue(你要设置的属性名, 你要设置的属性值)

    • 设置的时候,不管你写的是什么数据类型,倒流元素身上的时候,都会被自动转为 string 类型
二、getAttribute( )
  • 作用:获取元素的属性(可以获取元素属性,也可以获取自定义属性)

  • 语法:元素.getAttribute(你要获取的属性名)

  • 返回值:这个属性的值

    • 获取到的所有数据都是 string 数据类型
三、removeAttribute( )
  • 作用:删除元素的属性

  • 语法:元素.removeAttribute(你要删除的属性名)

四、attributes
  • 作用:获取元素的所有属性(可以获取原生属性, 也可以获取自定义属性)

  • 语法:元素.attributes

  • 返回值:一个obj(包含元素的所有属性和属性值)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div class="box">我是一个 div 标签</div>
  <script>
    // 0. 获取元素
    var div = document.querySelector('div')

    // 1. 给元素设置自定义属性
    // 给 div 这个元素身上设置了一个叫做 hello 的属性
    // 值就是 world
    div.setAttribute('hello', 'world')
    div.setAttribute('num', 10) // 设置的时候是赋值了一个 number 数据类型

    // 2. 获取元素的属性
    var res = div.getAttribute('hello')
    console.log(res) // world
    var res2 = div.getAttribute('num') // 获取元素身上叫做 num 的属性的值
    console.log(res2) // 10
    
    // 4.获取元素的所有属性
    var res3 = div.attributes
    console.log(res3)

    // 3. 删除元素属性
    div.removeAttribute('num') // 删除元素身上的 num 这个属性
    div.removeAttribute('hello') // 删除元素身上的 hello 这个属性
    div.removeAttribute('class') // 删除元素身上的 class 这个属性
  </script>
</body>
</html>

操作元素属性 - 类名

  • 专门用来操作元素类名的一个属性,因为 class 在 JS 里面有特殊含义,所以我们操作类名使用 className 这个属性
一、className
  • 是一个读写属性

  • 读:获取元素的类名

    • 有多少类名获取多少类名,以字符串的形式
    • 语法:元素.className
  • 写:设置元素的类名

    • 完全覆盖式写入
    • 语法:元素.className = '你要设置的类名’
  • 追加一个类名

    • 就是在原有的基础上添加一个类名
    • 可以使用 += 符号操作,并且在前面添加一个空格,和之前的类名隔开
二、案例
  • 案例1:获取元素的类名
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <!-- 元素 div 有三个类名, 分别是 a 和 b 和 c -->
  <div class="a b c"></div>

  <script>
    // 获取元素
    var div = document.querySelector('div')

    //获取元素的类名
    var cn = div.className
    console.log(cn) // 以字符串的形式获取到了元素 class 属性的所有值
  </script>
</body>
</html>
  • 案例2:设置元素的类名并且追加一个类名
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div></div>

  <script>
    // 获取元素
    var div = document.querySelector('div')

    // 设置元素的类名
    div.className = 'box1 box2' // 给元素设置两个类名, 分别是 box1 和 box2

    // 追加一个类名
    // 等价于 div.className = div.className + 'box3'
    div.className += ' box3' // 是不是追加了一个类名 ?
    // 你原先的类名是 'box1 + box2' === 'box1 box2'
    // 使用的时候要多加一个空格, 把他们隔开
  </script>
</body>
</html>

操作元素属性 - 样式

  • 操作元素的 css 样式
一、style 属性
  • 作用:获取到元素所有的可设置样式,值是一个对象

  • 语法:元素.style

  • 内容:是一个对象,里面有所有的元素可设置样式(但是值只有行内样式

读取元素的样式
  • 直接从对象里面获取就可以了

  • 你获取到的样式值,是带有单位的

  • 能拿到值的只有行内样式,非行内样式设置的值 style 拿不到

设置元素的样式
  • 直接给对象里面的某个成员修改值就可以了

  • JS 设置样式只能设置行内样式,不能设置非行内样式

注意:
  • 当你要操作一个带有**中划线(-)**的样式的时候

  • 比如:background-color, border-top, margin-top, …

  • 你操作的时候要转换写成驼峰的形式

  • background-color => backgroundColor

  • border-top => borderTop

  • margin-top => marginTop

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    div {
      height: 100px;
      background-color: pink;
    }
  </style>
</head>
<body>
  <div style="width: 100px; padding-top: 20px;"></div>

  <script>
    // 0. 获取元素
    var div = document.querySelector('div')

    // 1. 获取元素的 style
    var res = div.style
    console.log(res)
    
    // 2. 获取某一个样式
    var width = div.style.width
    console.log(width)
    var pt = div.style.paddingTop
    console.log(pt)
    
    // 3. 设置某一个样式
    div.style.height = '300px'
    div.style.borderTop = '10px solid #333'    
  </script>
</body>
</html>

二、同时设置多个样式
  • 语法:元素.style.cssText = '属性: 属性值;属性: 属性值;属性: 属性值; …'
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div style="width: 100px; padding-top: 20px;"></div>

  <script>
    var div = document.querySelector('div')
    div.style.cssText = 'width: 200px; height: 100px; background: red' 
  </script>
</body>
</html>


DOM节点

一、DOM树
  1. 根节点:Document(文档), 用来承载所有节点的, 组成一个页面

  2. 根元素节点:html 标签, 页面上最大的元素节点, 页面上最大的标签

  3. 普通元素节点:body / head / div / ul / li / script / …

  4. 文本节点:写在页面上的文本内容, 有可能被任何元素节点包裹

  5. 属性节点:写在每一个标签上的每一个属性, 必须要依赖于元素存在

  6. 注释节点:单独书写的一个节点, 表示注释内容, 不显示在页面上

二、节点操作
  • 对这些节点进行增删改查

节点属性

  • 每一节点都有自己的特点,这个节点属性就记录着属于自己的特点
一、nodeType(以一个数字来表示这个节点类型)
  • 语法:节点.nodeName

  • 得到:一个数字, 代表着这个节点的类型

    • 元素节点:1
    • 属性节点:2
    • 文本节点:3
    • 注释节点:8
  • 例子:将来我获取到某一个节点,我不确定它是不是元素节点,我只要判断它的 nodeType === 1 ,那么这个节点一定是元素节点

二、nodeName(节点名称)
  • 语法:节点.nodeName

  • 得到:一个名称, 属于这个节点的名称

    • 元素节点:大写标签名(全是大写)
    • 属性节点:属性名
    • 文本节点:#text(所有文本节点的名字都叫做 #text)
    • 注释节点:#comment(所有的注释节点名字都叫做 #comment)
  • 例子:将来我获取到某一个节点,确定了它是元素节点,但不确定是哪一个元素,我只要判断它的 nodeName === ‘DIV’, 就能确定他是一个 div 标签

三、nodeValue(节点的值)
  • 语法:节点.nodeValue

  • 得到:一个值,这个节点存储的值

    • 元素节点:null,元素节点没有值
    • 属性节点:属性的值
    • 文本节点:这个节点所代表的文本内容(包含换行和空格)
    • 注释节点:这个注释里面所写的文本内容(包含换行和空格)
节点属性元素节点属性节点文本节点注释节点
nodeType(节点类型)1238
nodeName(节点名称)大写标签名(全是大写)属性名#text#comment
nodeValue(节点的值)null属性值节点所代表的文本内容(包含换行和空格)注释里面所写的文本内容(包含换行和空格)
四、案例
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="box" class="box1 box2 box3">
    我是 div 内部的一个文本
    <!-- 我是一段注释内容 -->
  </div>

  <script>
    // 0. 获取到四种节点
    // 0-1. 获取元素节点 div
    var div = document.querySelector('div')   
    // 0-2. 获取一个属性节点(id="box")
    var attr = div.attributes[0]  
    // 0-3. 获取一个文本节点
    var text = div.childNodes[0]    
    // 0-4. 获取一个注释节点
    var comment = div.childNodes[1]
  

    // 1. nodeType
    console.log(div.nodeType) // => 元素节点的节点类型
    console.log(attr.nodeType) // => 属性节点的节点类型
    console.log(text.nodeType) // => 文本节点的节点类型
    console.log(comment.nodeType) // => 注释节点的节点类型

    // 2. nodeName
    console.log(div.nodeName) // => 元素节点的节点名称
    console.log(attr.nodeName) // => 属性节点的节点名称
    console.log(text.nodeName) // => 文本节点的节点名称
    console.log(comment.nodeName) // => 注释节点的节点名称

    // 3. nodeValue
    console.log(div.nodeValue) // => 元素节点的值
    console.log(attr.nodeValue) // => 属性节点的值
    console.log(text.nodeValue) // => 文本节点的值
    console.log(comment.nodeValue) // => 注释节点的值
  </script>
</body>
</html>

获取节点的操作

  • 获取某一个元素节点的相关节点,下面的所有语法都是 元素.xxx
一、childNodes 属性
  • 作用:获取到一个元素节点下所有的子节点

  • 语法:元素.childNodes

  • 得到:是一个伪数组,里面是所有的子节点

二、children 属性
  • 作用:获取到一个元素节点下所有的 子元素节点

  • 语法:元素.children

  • 得到:是一个伪数组,里面是所有的子元素节点

三、firstChild 属性
  • 作用:获取到一个元素节点下的第一个 子节点

  • 语法:元素.firstChild

  • 得到:一个节点(有可能是任何节点)

四、firstElementChild 属性
  • 作用:获取到一个元素节点下的第一个 子元素节点

  • 语法:元素.firstElementChild

  • 得到:一个元素节点

五、lastChild 属性
  • 作用:获取到一个元素节点下的最后一个 子节点

  • 语法元素.lastChild

  • 得到:一个节点(有可能是任何节点)

六、lastElementChild 属性
  • 作用:获取到一个元素节点下的最后一个 子元素节点

  • 语法:元素.lastElementChild

  • 得到:一个元素节点

七、previousSibling 属性
  • 作用:获取到一个元素节点的上一个 兄弟节点(上一个哥哥节点)

  • 语法:元素.previousSibling

  • 得到:一个节点(有可能是任何节点)

八、previousElementSibling 属性
  • 作用:获取到一个元素节点的上一个 兄弟元素节点(上一个哥哥元素)

  • 语法:元素.previousElementSibling

  • 得到:一个元素节点

九、nextSibling 属性
  • 作用:获取到一个元素节点的下一个 兄弟节点(下一个弟弟节点)

  • 语法:元素.nextSibling

  • 得到:一个元素节点(有可能是任何节点)

十、nextElementSibling 属性
  • 作用:获取到一个元素节点的下一个 兄弟元素节点(下一个弟弟元素)

  • 语法:元素.nextElementSibling

  • 得到:一个元素节点

十一、parentNode 属性
  • 作用:获取到一个元素节点的 父节点

    • 一般来说,我们能作为父子关系的,父亲一般就是元素节点
    • 有特殊,但很少,比如 document 就可以作为父节点,但不是元素节点
  • 语法元素.parentNode

  • 得到:一个节点(有可能是元素节点,也有可能是根节点)

十二、parentElement 属性
  • 作用:获取到一个元素的 父元素节点

  • 语法:元素.parentElement

  • 得到:一个元素节点

十三、attributes 属性
  • 作用:获取一个元素的所有 属性节点

    • 因为属性节点不作为独立节点存在,必须历来元素节点存在,所以他不和任何内容出现父子关系
  • 语法:元素.attributes

十四、案例
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>

  <p>我是 div 前面的一个 p 标签</p>
  <div class="box" id="box" hello="world" num="10">
    <p>一号</p>
    <span>二号</span>
    <!-- 注释 -->
    hello world
  </div>
  <p>我是 div 后面的一个 p 标签</p>

  <script>
    /*
       html 是最大的元素节点, 他没有 父元素 只有 父节点
       div
       div 的 父节点 是 body
       div 的 父节点 的 父节点 是 html
       div 的 父节点 的 父节点 的 父节点 是 document
    */

    // 0. 获取元素
    var div = document.querySelector('div')

    // 1. childNodes
    // 获取 div 这个元素下的所有 **子节点**
    console.log(div.childNodes)

    // 2. children
    // 获取 div 这个元素下的所有 **子元素节点**
    console.log(div.children)

    // 3. firstChild
    // 获取 div 这个元素下的第一个 **子节点**
    console.log(div.firstChild)

    // 4. firstElementChild
    // 获取 div 这个元素下的第一个 **子元素节点**
    console.log(div.firstElementChild)

    // 5. lastChild
    // 获取 div 这个元素下的最后一个 **子节点**
    console.log(div.lastChild)

    // 6. lastElementChild
    // 获取 div 这个元素下的最后一个 **子元素节点**
    console.log(div.lastElementChild)

    // 7. previousSibling
    // 获取 div 这个元素的上一个 **兄弟节点**
    console.log(div.previousSibling)

    // 8. previousElementSibling
    // 获取 div 这个元素的上一个 **兄弟元素节点**
    console.log(div.previousElementSibling)

    // 9. nextSibling
    // 获取 div 这个元素的下一个 **兄弟节点**
    console.log(div.nextSibling)

    // 10. nextElementSibling
    // 获取 div 这个元素的下一个 **兄弟元素节点**
    console.log(div.nextElementSibling)

    // 11. parentNode
    // 获取 div 这个元素的 **父节点**
    console.log(div.parentNode.parentNode.parentNode) // document

    // 12. parentElement
    // 获取 div 这个元素的 **父元素节点**
    console.log(div.parentElement.parentElement.parentElement) // null

    // 13. attributes
    // 获取 div 这个元素的所有 **属性节点**
    console.log(div.attributes)
  </script>
</body>
</html>

节点操作 - 创建节点

  • 创建节点 - 通过 JS 代码创建一个标签
一、document.createElement( )
  • 作用:在文档流里面创建一个元素节点

  • 语法:document.createElement(‘你要创建的元素节点名称小写就行’)

  • 返回值:就是一个创建好的元素节点

    • 和你在页面上获取的元素节点没有任何区别
    • 只不过创建出来的节点没有在页面上
二、document.createTextNode( )
  • 作用:在文档流里面创建一个文本节点

  • 语法:document.createTextNode(‘你要创建的文本内容’)

  • 返回值:就是一个文本节点

    • 和你在页面上获取来的文本节点一样,没有区别
    • 只不过一个在页面上,一个是我凭空捏造的
三、案例
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="innerPage">我是页面上的一个 div 标签</div>
  <script>
    // 0. 获取页面上的 div 标签
    var div = document.querySelector('div')
    div.innerHTML = '我是一段文本内容'
    div.className = 'box1 box2'
    console.log(div)

    // 1. 创建一个 div 标签
    var creDiv = document.createElement('div')
    creDiv.innerHTML = '我是一段文本内容'
    creDiv.className = 'box3 box4'
    console.log(creDiv)

    // 2. 创建一个文本节点
    var text = document.createTextNode('我是凭空捏造的一个节点')
    console.log(text.nodeType)
    console.log(text.nodeName)
    console.log(text.nodeValue)
  </script>
</body>
</html>

节点操作 - 插入节点

  • 就是把一个节点添加到另一个节点里面作为子节点使用
  • 注意:一般都是把节点添加到某一个元素节点里面
  • 你也可以添加到一个从页面中获取的节点里面
  • 也可以添加到一个你创建的节点里面
一、appendChild( )
  • 作用:向某一个父节点内追加一个子节点

  • 语法:父节点.appendChild(要追加的子节点)

  • 结果:子节点被添加到父节点里面了,排在所有节点的最后一个位置

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div>
    我是页面本身的 div 标签
    <p class="a">我是 div 内部本身的 p 标签</p>
    <p class="b">我是 div 内部本身的 p 标签</p>
    <p class="c">我是 div 内部本身的 p 标签</p>
    <p>我是 div 内部本身的 p 标签</p>
    <p>我是 div 内部本身的 p 标签</p>
  </div>

  <script>
    // 0. 获取页面中的 div 节点
    var div = document.querySelector('div')
    // 0. 获取页面中的 p 节点
    var p = document.querySelector('.c')

    // 1. 创建一个 span 节点
    var creSpan = document.createElement('span')
    creSpan.innerHTML = '我是创建的一个 span 标签'

    // 2. 把创建的 span 插入到 div 的内部, 并且放在 p 标签的前面
    // 2-1. 看一下 appendChild 的效果
    div.appendChild(creSpan)
  </script>
</body>
</html>
二、insertBefore( )
  • 作用:向某一个父节点内插入一个子节点,插入到本身的某一个子节点的前面

  • 语法:父节点.insertBefore(你要插入的节点, 那一个已经存在的子节点前面)

  • 结果:就是把该节点插入到父节点的指定节点前面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div>
    我是页面本身的 div 标签
    <p class="a">我是 div 内部本身的 p 标签</p>
    <p class="b">我是 div 内部本身的 p 标签</p>
    <p class="c">我是 div 内部本身的 p 标签</p>
    <p>我是 div 内部本身的 p 标签</p>
    <p>我是 div 内部本身的 p 标签</p>
  </div>

  <script>
    // 0. 获取页面中的 div 节点
    var div = document.querySelector('div')
    // 0. 获取页面中的 p 节点
    var p = document.querySelector('.c')

    // 1. 创建一个 span 节点
    var creSpan = document.createElement('span')
    creSpan.innerHTML = '我是创建的一个 span 标签'

    // 2. 把创建的 span 插入到 div 的内部, 并且放在 p 标签的前面
    // 2-1. 看一下 insertBefore 的效果
    div.insertBefore(creSpan, p)
  </script>
</body>
</html>

节点操作 - 删除节点

  • 就是把一个已经存在的节点移除
  • 你可以从页面的某一个节点里面移除
  • 也可以从你创建的某一个节点里面移除
一、removeChild( )
  • 作用:从父节点里面移除某一个子节点

  • 语法:父节点.removeChild(你要移除的子节点)

  • 结果:该父节点里面不再有这个子节点了

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div>
    <p>我是 div 里面的一个 p 标签 一号</p>
    <p>我是 div 里面的一个 p 标签 二号</p>
    <span>我是 div 里面的一个 span 标签</span>
  </div>

  <script>
    // 0. 获取元素
    var div = document.querySelector('div')
    var p = document.querySelector('p') // 我这里获取到的就是 一号

    // 1. 把 p 标签从 div 里面移除
    div.removeChild(p) // 移除的也是 div 里面的 一号 p 标签
  </script>
</body>
</html>
二、remove( )
  • 作用:把自己移除

  • 语法:要移除的节点.remove()

  • 结果:自己直接被移除掉

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div>
    <p>我是 div 里面的一个 p 标签 一号</p>
    <p>我是 div 里面的一个 p 标签 二号</p>
    <span>我是 div 里面的一个 span 标签</span>
  </div>

  <script>
    // 0. 获取元素
    var div = document.querySelector('div')

    // 1. 把 div 自己从页面里面 直接移除
    div.remove() // 移除的是 div 以及 div 里面所有的子节点
  </script>
</body>
</html>

节点操作 - 替换节点

  • 就是用某一个节点,去替换一个已经存在的节点
一、replaceChild( )
  • 作用:就是把父节点下的某一个子节点替换成新节点

  • 语法:父节点.replaceChild(新节点, 旧节点)

  • 结果:使用新节点,把旧节点替换掉

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div>
    <p>我是 div 里面本身就存在的 p 标签</p>
  </div>
  <script>
    // 0. 获取元素
    var div = document.querySelector('div')
    var p = document.querySelector('p')

    // 1. 创建一个 span 标签
    var creSpan = document.createElement('span')
    creSpan.innerHTML = '我是创建的一个 span 标签'

    // 2. 用我创建的 span 标签把 div 里面本身的 p 标签替换掉
    div.replaceChild(creSpan, p)
  </script>
</body>
</html>

节点操作 - 克隆节点

  • 把一个已经存在的节点(可以是从页面里获取的,也可以是自己创建的)
  • 复制一份一模一样的出来
  • 克隆出来的标签不在页面上,是在js代码里面(在内存里面)
  • 你想让克隆出来的标签放在哪里,就自己使用插入到页面的方法去插入
一、cloneNode( )
  • 作用:把节点复制一份一模一样的

  • 语法:要克隆的节点.cloneNode(参数选填)

    • 参数默认是是false,表示不克隆后代节点
    • 参数可以选填true,表示克隆所有后代节点
  • 返回值:就是一个已经被克隆好的节点

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div class="box" style="width: 100px; height: 100px;">
    <p>我是 div 里面本身就存在的 p 标签</p>
  </div>

  <script>
    // 0. 获取元素
    var div = document.querySelector('div')
	
	// 克隆元素
    var res = div.cloneNode(true)
    res.style.border = '20px solid red'
    res.className += ' box10'
    console.log(res)

    // 2. 把克隆的节点插入到页面里面
    var body = document.querySelector('body')
    body.appendChild(res)
  </script>
</body>
</html>

获取元素偏移量 - 参考系

  • 假设你要给一个元素设置绝对定位的时候, 他根据谁来定位
  • 当你获取这个元素的偏移量的时候, 他的参考父元素就是谁
  • 一个元素的偏移量参考元素就是这个元素的定位父级
一、offsetParent 属性
  • 作用:获取元素的偏移量参考父元素

  • 语法:元素:元素.offsetParent

  • 得到:就是你这个元素获取偏移量的时候是根据谁来的

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

  <script>
    // 1. 获取元素
    var span = document.querySelector('span')
    // 打印看一下 span 这个元素的偏移量参考父元素
    console.log(span.offsetParent)
  </script>
</body>
</html>

获取元素偏移量 - 元素偏移量

一、offsetLeft
  • 语法:元素.offsetLeft

  • 得到:元素相对于参考元素左侧的距离

二、offsetTop
  • 语法:元素.offsetTop

  • 得到:元素相对于参考元素上边的距离

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    div {
      margin: 30px;
      width: 500px;
      height: 500px;
      background-color: skyblue;
      overflow: hidden;
      position: relative;
    }
    p {
      width: 300px;
      height: 300px;
      margin: 20px;
      background-color: pink;
      overflow: hidden;
      position: relative;
    }
    span {
      display: block;
      width: 100px;
      height: 100px;
      background-color: red;
      margin: 10px;
      /* 现在还是根据 p 来定位呢 */
      position: absolute;
      top: 10px;
      left: 10px;
    }
  </style>
</head>
<body>
  <div>
    <p>p
      <span>span</span>
    </p>
  </div>

  <script>
    // 0. 获取元素
    var span = document.querySelector('span')
    // 1. 打印看一下元素的偏移量参考元素
    console.log('参考元素 : ', span.offsetParent) 
    // 2. 打印看一下左边的距离
    console.log('左边的距离 : ', span.offsetLeft) // 20
    // 3. 打印看一下上边的距离
    console.log('上边的距离 : ', span.offsetTop) // 20
  </script>
</body>
</html>


获取元素尺寸

  • 获取元素在页面上的占地面积
  • display: none; 获取不到页面上的占地面积(消失不占位)
  • visibility: hidden; 可以获取到页面上的占地面积(消失占位)
  • opacity: 0; 可以获取到页面上的占地面积(不显示,但占位)
  • 注意:获取到的是没有单位的数字,可以直接参与运算
一、offsetWidth 和 offsetHeight
  • 获取到的是元素的 边框 + 内边距 + 内容 区域的尺寸
  • offsetWidth 是宽度
  • offsetHeight 是高度
  • 不管盒子模型是什么状态,拿到的都是 边框 + 内边距 + 内容 区域的尺寸
二、clientWidth 和 clientHeight
  • 获取到的是元素的 内边距 + 内容 区域的尺寸

  • clientWidth 是宽度

  • clientHeight 是高度

  • 不管盒子模型是什么状态,拿到的都是 内边距 + 内容 区域的尺寸

    元素尺寸尺寸
    offsetWidthborder + padding + width
    offsetHeightborder + padding + height
    clientWidthpadding + width
    clientHeightpadding + height
  • 案例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    div {
      width: 300px;
      height: 300px;
      padding: 20px;
      margin: 30px;
      border: 10px solid #333;
      background-color: skyblue;

      /* 内减模式, 怪异盒模型 */
      /* box-sizing: border-box; */
    }
  </style>
</head>
<body>
  <div></div>

  <script>
    // 0. 获取元素
    var div = document.querySelector('div')

    // 1. offsetWidth 和 offsetHeight
    console.log('元素的 offsetWidth 是 : ', div.offsetWidth) // 360
    console.log('元素的 offsetHeight 是 : ', div.offsetHeight) // 360

    // 2. clientWidth 和 clientHeight
    console.log('元素的 clientWidth 是 : ', div.clientWidth) // 340
    console.log('元素的 clientHeight 是 : ', div.clientHeight) // 340
  </script>
</body>
</html>

各类尺寸总结

条件/类型语法
元素相对于参考元素左侧的距离offsetLeft
元素相对于参考元素上边的距离offsetTop
整个盒子的宽度:border + padding + widthoffsetWidth
整个盒子的高度:border + padding + heightoffsetHeight
盒子内容的宽度:padding + widthclientWidth
盒子内容的高度:padding + heightclientHeight
鼠标到浏览器可视窗口左边的距离e.clientX
鼠标到浏览器可视窗口上边的距离e.clientY
鼠标到页面最左边的距离(包含被卷去的宽度)e.pageX
鼠标到页面最上边的距离(包含被卷去的高度)e.pageY
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值