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寻找符合条件的对象等等,在此不做展开了。

相关文章
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
666 57
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
编解码 JavaScript 前端开发
【Java进阶】详解JavaScript的BOM(浏览器对象模型)
总的来说,BOM提供了一种方式来与浏览器进行交互。通过BOM,你可以操作窗口、获取URL、操作历史、访问HTML文档、获取浏览器信息和屏幕信息等。虽然BOM并没有正式的标准,但大多数现代浏览器都实现了相似的功能,因此,你可以放心地在你的JavaScript代码中使用BOM。
417 23
|
XML 编解码 JavaScript
DOM(文档对象模型)和 BOM(浏览器对象模型)
【10月更文挑战第19天】在前端开发中,理解 DOM(文档对象模型)和 BOM(浏览器对象模型)是至关重要的。它们是 Web 开发的基础,为我们提供了与网页文档和浏览器进行交互的能力。
2034 62
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
JSON 前端开发 JavaScript
JavaScript中对象的数据拷贝
本文介绍了JavaScript中对象数据拷贝的问题及解决方案。作者首先解释了对象赋值时地址共享导致的值同步变化现象,随后提供了五种解决方法:手动复制、`Object.assign`、扩展运算符、`JSON.stringify`与`JSON.parse`组合以及自定义深拷贝函数。每种方法都有其适用场景和局限性,文章最后鼓励读者关注作者以获取更多前端知识分享。
331 1
JavaScript中对象的数据拷贝
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
1170 5
|
JavaScript 前端开发 开发者
.js的dom元素操作
【10月更文挑战第29天】通过灵活运用这些 DOM 元素操作方法,JavaScript 可以实现丰富的网页交互效果,如动态更新页面内容、响应用户操作、创建和删除页面元素等。在实际开发中,开发者可以根据具体的需求和场景,选择合适的 DOM 元素操作方法来实现所需的功能,为用户提供更加流畅和动态的网页体验。