JavaScript:DOM对象

简介: JavaScript:DOM对象

DOM与JavaScript的关系

严格意义上讲,我们在 JavaScript 语法阶段学习的知识绝大部分属于 ECMAScript 的知识体系,ECMAScript 简称 ES 它提供了一套语言标准规范,如变量、数据类型、表达式、语句、函数等语法规则都是由 ECMAScript 规定的。浏览器将 ECMAScript 大部分的规范加以实现,并且在此基础上又扩展一些实用的功能,这些被扩展出来的内容我们称为 Web APIs。

ECMAScript 运行在浏览器中然后再结合 Web APIs 才是真正的 JavaScript,Web APIs 的核心是 DOM 和 BOM。


什么是DOM

DOM(Document Object Model)是将整个 HTML 文档的每一个标签元素视为一个对象,这个对象下包含了许多的属性和方法,通过操作这些属性或者调用这些方法实现对 HTML 的动态更新,为实现网页特效以及用户交互提供技术支撑。

简言之 DOM 是用来动态修改 HTML 的,其目的是开发网页特效及用户交互。

观察一个小例子:

上述的例子中当用户分分别点击【开始】或【结束】按钮后,通过右侧调试窗口可以观察到 html 标签的内容在不断的发生改变,这便是通过 DOM 实现的。

DOM是浏览器提供的专门用来操纵网页内容的功能


DOM相关概念

DOM 树

我们有以下HTML代码,现在将其转化为DOM树结构:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>标题</title>
</head>
<body>
  文本
  <a href="">链接名</a>
  <div id="" class="">文本</div>
</body>
</html>

如下图所示:

在HTML文件中,我们的总文档为document,内部有HTML大标签,HTML内有head和body;在head内又有meta,title等等。

这样一直深入,我们就得到了标签之间的层级关系,最后用树状结构展示出来,我们就得到了DOM树。

将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树文档树直观的体现了标签与标签之间的关系。


DOM 节点

节点是文档树的组成部分,每一个节点都是一个 DOM 对象,主要分为元素节点、属性节点、文本节点等。

  1. 【元素节点】其实就是 HTML 标签,如上图中 headdivbody 等都属于元素节点。
  2. 【属性节点】是指 HTML 标签中的属性,如上图中 a 标签的 href 属性、div 标签的 class属性。
  3. 【文本节点】是指 HTML 标签的文字内容,如 title 标签中的文字。
  4. 【根节点】特指 html 标签。
  5. 其它…

要注意,节点是在DOM树中的概念,而对象是JavaScript中的概念,简单来说,这个DOM树转化为DOM对象后,我们就可以在JavaScript中操作对象,从而操纵网页标签。


DOM对象

DOM对象是浏览器根据HTML标签生成的JavaScript对象

我们在讲解DOM节点时已经大致提到,DOM是通过将HTML的标签转化为JavaScript对象从而实现的对HTML操控。

document 是 JavaScript 内置的专门用于 DOM 的对象,该对象包含了若干的属性和方法。

我们先讲解一个熟悉的代码:

document.write('Hello World!');

这是一个在语法阶段就已经学习过的向浏览器页面写入的语句,观察其结构开头是document ,后面有一个点号.紧接着的是一个函数write()。这串代码的突破点在于这个点号.,点号是JavaScript的对象访问使用的操作符,也就是说document是一个对象,这串代码正在访问document对象中的write()方法(即函数)。

而这个 document.write('Hello World!');过程,就是向网页中写入字符串’Hello World!',这是一个通过JavaScript操作网页的过程,我们使用了document对象。

由此可见:

document确实是一个对象

我们可以通过document对象操控网页


获取DOM对象

刚刚的document对象,我们是可以直接使用的,而在DOM树中,不止document一个对象,对象的某个熟悉也可以是对象,比如document下面的html,body,head都是一个对象。当我们想要操纵这些小对象时,我们要先获取到这个对象。

通过CSS选择器来获取DOM对象

我们有两种方式可以通过CSS的选择器来获取对象分别是querySelector()和querySelectorAll():

这两个方式,都是函数,我们需要向函数传参,参数就是CSS的选择器。在此,选择器既可以是基本选择器,也可以是复合选择器。由于复合选择器可以非常精确的定位的元素,通过选择器获取到的DOM对象也会十分精准,这是获取对象最好用,最主要的方式。

querySelector

语法:

const/let/var 变量 = document.querySelector('CSS选择器') 

既然是DOM树的内容,毫无疑问要通过document对象出发,所以querySelector也是一个document对象的方法。这个querySelector会返回一个对象,也就是符合我们条件的对象,比如document.querySelector('.box p')这串代码就是获得了类名为box的父级元素里面的p标签。

但是要注意,querySelector只能获取第一个符合条件的元素

当我们获取到对象后,就要用变量来接收它,此处用const/let/var三种关键字来定义变量都可以,但是由于我们的对象一般是不修改的,最好使用const。

这个方式只能得到第一个符合条件的元素,我们第二种方法就是来获取所有符合条件的元素的:

querySelectorAll

语法:

const/let/var 变量 = document.querySelectorAll('CSS选择器')  

和刚才的语法是一致的,但是它可以获取符合条件的所有对象,那么最后要如何让一个变量同时接收所有符合条件的对象?

我们先用一串代码观察一下:

<ul>
      <li>元素</li>
      <li>元素</li>
      <li>元素</li>
      <li>元素</li>
  </ul>
  <script>
    const lis = document.querySelectorAll('li');
    console.log(lis);
  </script>

这串代码中const lis = document.querySelectorAll('li');就是在获取所有的li标签,因为CSS中li这个选择器就是一个标签选择器,选择了所有li标签。

输出结果:

可以看到,我们的lis,即我们获取的返回值,其实是一个数组,数组里面有符合条件的所有对象。

结论:querySelectorAll可以获得所有符合条件的元素,将它们存放在一个数组中

但是其实这个数组是一个伪数组,它有数组的形式,但是没有数组的所有功能,它不能使用数组的pop(),push()等方法。


其他方式

getElementById

getElementsByTagName

getElementsByClassName

通过这三个名字就可以看出来,getElementById是通过id选择器来获取元素;getElementsByTagName是通过标签名来获得一类元素;getElementsByClassName是通过类选择器来获得元素。

对于这些方式,我们不过多讲解,querySelector()和querySelectorAll()已经足够好用,这些只做了解。


操作DOM对象

我们已经获得到了DOM对象,接下来就要学习如何通过DOM对象来操控页面内的元素了:

控制DOM对象内容

通过修改 DOM 的文本内容,动态改变网页的内容。

什么是DOM对象的内容?比如我们有一个li标签:<li>你好</li>,其中“你好”这个字符串就是li标签的内容,当我们获取到li标签的对象,就可以修改其内部的内容了。

  1. innerText 将文本内容添加/更新到任意标签,文本中包含的标签不会被解析。
<script>
  const intro = document.querySelector('.intro')
  intro.innerText = '嗨~ 我叫李雷!'
  intro.innerText = '<h4>嗨~ 我叫李雷!</h4>'
</script>

代码解析

首先,我们通过const intro = document.querySelector('.intro'),获取到了类名为intro的元素对象,innerText 可以在对象内部写入文本,比如第二句代码中:intro.innerText = '嗨~ 我叫李雷!'就是在我们对象对应的标签中写入“嗨~ 我叫李雷!”这个字符串。

但是这样写入的文本,不会被解析,这是什么意思?我们看到第三行代码:

我们通过innerText向网页写入了一个字符串,字符串被h4标签包裹,我们运行一下看看效果:

最后我们的<h4></h4>没有被解析为标签,而是被解析为了文本。

  1. innerHTML 将文本内容添加/更新到任意标签位置,文本中包含的标签会被解析。
<script>
  const intro = document.querySelector('.intro')
  intro.innerHTML = '嗨~ 我叫韩梅梅!'
  intro.innerHTML = '<h4>嗨~ 我叫韩梅梅!</h4>'
</script>

其与innerText的唯一区别就是,它可以解析HTML标签,我们再运行一下试试看:

此时我们的<h4></h4>就被解析为了四级标题标签。

在实际开发中,绝大部分场景都使用 innerHTML ,除非你真的想在网页内输出文本形式的标签。


控制DOM对象属性

控制HTML标签属性

对于一些简单的HTML属性,它们会被存放在相应的对象中,需要使用时直接调用即可:

语法:

对象.属性 = 值

示例:

<script>
  // 1. 获取 img 对应的 DOM 元素
  const pic = document.querySelector('.pic')
  // 2. 修改属性
  pic.src = './images/lion.webp'
  pic.width = 400;
  pic.alt = '图片不见了...'
</script>

src,alt,width都是HTML中的img自带的属性,它们本身就存在于img的对象中,需要时直接调用,对其赋值即可。

绝大部分在HTML中直接出现的标签属性值,都可以用这种方式来修改。


控制CSS样式
通过style属性操作CSS

先前的属性,是直接在HTML中可以使用的属性,而绝大部分属性,是处于CSS中的,在这一类属性,会存在于DOM对象的style属性中。

语法:

对象.style.属性 = “属性值”

通过元素节点获得的 style 属性本身的数据类型也是对象,如 box.style.colorbox.style.width 分别用来获取元素节点 CSS 样式的 colorwidth 的值。

示例:

<div class="box">随便一些文本内容</div>
  <script>
    // 获取 DOM 节点
    const box = document.querySelector('.intro')
    box.style.color = 'red'
    box.style.width = '300px'
    box.style.backgroundColor = 'skyblue'
  </script>

css 属性的 - 连接符与 JavaScript 的 减运算符冲突,此时要改为驼峰命名法。

任何标签都有 style 属性,通过 style 属性可以动态更改网页标签的样式,如要遇到 css 属性中包含字符 - 时,要将 - 去掉并将其后面的字母改成大写,如 background-color 要写成 box.style.backgroundColor


通过类名(className) 操作CSS

如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。

DOM对象有一个属性className,其存储这这个元素具有的CSS类,当我们想要修改的值太多,就可以把修改后的值都写到一个类选择器中,然后将对象的类修改为对于的类选择器。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>练习 - 修改样式</title>
    <style>
        .blue {
            background: blue;
            color: skyblue;
        }
    </style>
</head>
<body>
  <div class="box">随便一些文本内容</div>
  <script>
    // 获取 DOM 节点
    const box = document.querySelector('.intro')
    box.className = 'blue'
  </script>
</body>
</html>

解析:

在上述代码这种,我们提取了box这个对象,然后将字体颜色和背景封装在了一个名为blue的类中,当我们想要在JavaScript中改变box的字体颜色和背景,只需要将blue这个类给box即可。

注意:

className是使用新值换旧值, 我们在添加新的类后,原先的类会被覆盖

基于这个特性,这个方法其实并不好用,而下一个方法可以非常好的解决这个问题。


通过 classList 操作类控制CSS

为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名

classList是DOM对象所具有的全部类的集合,classList下面有方法可以实现类的追加和删除:

追加:

对象.classList.add('类名')

删除:

对象.box.classList.remove('类名')

切换状态(有就删掉,没有就加上):

对象.box.classList.toggle('类名')

示例:

<!DOCTYPE html>
<html lang="en">
<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>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
        .active {
            width: 300px;
            height: 300px;
            background-color: hotpink;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="one"></div>
    <script>
        // 1.获取元素
        let box = document.querySelector('div')
        // add是个方法 添加  追加
        box.classList.add('active')
        // remove() 移除 类
        box.classList.remove('one')
        // 切换类
        box.classList.toggle('one')
    </script>
</body>
</html>

自定义属性

标准属性: 标签天生自带的属性 比如class id title等, 可以直接使用点语法操作比如: disabled、checked、selected

自定义属性:

在html5中推出来了专门的data-自定义属性,在标签上一律以data-开头,在DOM对象上一律以dataset.对象方式获取。

<body>
   <div data-id="1"> </div>
    <script>
        // 1. 获取元素
        let div = document.querySelector('div')
        // 2. 获取自定义属性值
         console.log(div.dataset.id)
    </script>
</body>

这里的自定义属性值,可以存一些标识符号,用于后续JavaScript寻找符合条件的对象等等,在此不做展开了。

相关文章
|
6天前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
18 3
|
19天前
|
JavaScript
JS 获取对象数据类型的键值对的键与值
JS 获取对象数据类型的键值对的键与值
|
1天前
|
前端开发 JavaScript 数据安全/隐私保护
前端javascript的DOM对象操作技巧,全场景解析(二)
前端javascript的DOM对象操作技巧,全场景解析(二)
|
1天前
|
移动开发 缓存 JavaScript
前端javascript的DOM对象操作技巧,全场景解析(一)
前端javascript的DOM对象操作技巧,全场景解析(一)
|
1天前
|
JavaScript 前端开发
JavaScript DOM 文档对象模型(获取、改变html元素)
JavaScript DOM 文档对象模型(获取、改变html元素)
|
8天前
|
JavaScript 前端开发 UED
深入解析JavaScript原生操作DOM技术
【4月更文挑战第22天】本文深入探讨JavaScript原生DOM操作技术,包括使用`getElement*`方法和CSS选择器获取元素,借助`createElement`与`appendChild`动态创建及插入元素,修改元素内容、属性和样式,以及删除元素。通过掌握这些技术,开发者能实现页面动态交互,但应注意避免过度操作DOM以优化性能和用户体验。
|
8天前
|
JavaScript 前端开发 开发者
JavaScript中的错误处理:try-catch语句与错误对象
【4月更文挑战第22天】JavaScript中的错误处理通过try-catch语句和错误对象实现。try块包含可能抛出异常的代码,catch块捕获并处理错误,finally块则无论是否出错都会执行。错误对象提供关于错误的详细信息,如类型、消息和堆栈。常见的错误类型包括RangeError、ReferenceError等。最佳实践包括及时捕获错误、提供有用信息、不忽略错误、利用堆栈信息和避免在finally块中抛错。
|
12天前
|
JavaScript 前端开发
JavaScript BOM 浏览器对象模型
JavaScript BOM 浏览器对象模型
|
12天前
|
JavaScript 前端开发 API
JavaScript DOM 文档对象模型
JavaScript DOM 文档对象模型
|
14天前
|
JavaScript
【Js】检查Date对象是否为Invalid Date
【Js】检查Date对象是否为Invalid Date
18 0