认识DOM和架构

news2025/1/17 15:51:05

DOM 代表文档对象模型,是 HTML 和 XML 文档的接口(API)。当浏览器第一次读取(解析)HTML文档时,它会创建一个大对象,一个基于 HTM L文档的非常大的对象,这就是DOM。它是一个从 HTML 文档中建模的树状结构。DOM 用于交互和修改DOM结构或特定元素或节点。

浏览器是用来展示网页的,而网页中最重要的就是里面各种的标签元素,JavaScript很多时候是需要操作这些元素的。

JavaScript如何操作元素呢?通过Document Object Model(DOM,文档对象模型)。
DOM给我们提供了一系列的模型和对象,让我们可以方便的来操作Web页面。

图片10.png

EventTarget

因为继承自EventTarget,所以也可以使用EventTarget的方法:

document.addEventListener("click", () => {
  console.log("document被点击")
})

const divEl = document.querySelector("#box")
const spanEl = document.querySelector(".content")

divEl.addEventListener("click", () => {
  console.log("div元素被点击")
})

spanEl.addEventListener("click", () => {
  console.log("span元素被点击")
})

Node节点

所有的DOM节点类型都继承自Node接口。

详细参考MDN文档:https://developer.mozilla.org/zhCN/docs/Web/API/Node

Node有几个非常重要的属性:

  • nodeName:node节点的名称。
  • nodeType:可以区分节点的类型。
  • nodeValue:node节点的值;
  • childNodes:所有的子节点;
const divEl = document.querySelector("#box")
const spanEl = document.querySelector(".content")

// 常见的属性
console.log(divEl.nodeName, spanEl.nodeName)
console.log(divEl.nodeType, spanEl.nodeType)
console.log(divEl.nodeValue, spanEl.nodeValue)

// childNodes
const spanChildNodes = spanEl.childNodes
const textNode = spanChildNodes[0]
console.log(textNode.nodeValue)


// 常见的方法
const strongEl = document.createElement("strong")
strongEl.textContent = "我是strong元素"
divEl.appendChild(strongEl)

// 注意事项: document对象
document.body.appendChild(strongEl)

Document

Document节点表示的整个载入的网页,我们来看一下常见的属性和方法:

// 常见的属性
console.log(document.body)
console.log(document.title)
document.title = "Hello World"

console.log(document.head)
console.log(document.children[0])

console.log(window.location)
console.log(document.location)
console.log(window.location === document.location)

// 常见的方法
// 创建元素
const imageEl = document.createElement("img")
const imageEl2 = new HTMLImageElement()

// 获取元素
const divEl1 = document.getElementById("box")
const divEl2 = document.getElementsByTagName("div")
const divEl3 = document.getElementsByName("title")
const divEl4 = document.querySelector(".content")
const divEl5 = document.querySelectorAll(".content")

Element

我们平时创建的div、p、span等元素在DOM中表示为Element元素,我们来看一下常见的属性和方法:

const divEl = document.querySelector("#box")


// 常见的属性
console.log(divEl.id)
console.log(divEl.tagName)
console.log(divEl.children)
console.log(divEl.className)
console.log(divEl.classList)
console.log(divEl.clientWidth)
console.log(divEl.clientHeight)
console.log(divEl.offsetLeft)
console.log(divEl.offsetTop)

// 常见的方法
const value = divEl.getAttribute("age")
console.log(value)
divEl.setAttribute("height", 1.88)

认识事件监听

前面我们讲到了JavaScript脚本和浏览器之间交互时,浏览器给我们提供的BOM、DOM等一些对象模型。

  • 事实上还有一种需要和浏览器经常交互的事情就是事件监听:
  • 浏览器在某个时刻可能会发生一些事件,比如鼠标点击、移动、滚动、获取、失去焦点、输入内容等等一系列的事件;

我们需要以某种方式(代码)来对其进行响应,进行一些事件的处理; 在Web当中,事件在浏览器窗口中被触发,并且通过绑定到某些元素上或者浏览器窗口本身,那么我们就可以给这些元素或者window窗口来绑定事件的处理程序,来对事件进行监听。

如何进行事件监听呢?

  • 事件监听方式一:在script中直接监听;
  • 事件监听方式二:通过元素的on来监听事件;
  • 事件监听方式三:通过EventTarget中的addEventListener来监听;

认识事件流的由来

事实上对于事件有一个概念叫做事件流,为什么会产生事件流呢?

  • 我们可以想到一个问题:当我们在浏览器上对着一个元素点击时,你点击的不仅仅是这个元素本身;
  • 这是因为我们的HTML元素是存在父子元素叠加层级的;
  • 比如一个span元素是放在div元素上的,div元素是放在body元素上的,body元素是放在html元素上的;
<!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>
    .box {
      width: 200px;
      height: 200px;
      background-color: red;
    } 

    body {
      background-color: yellow;
    }
  </style>
</head>
<body>
  <div class="box" onclick="console.log('div元素被点击')"></div> -->
</body>
</html>


function divClick() {
  console.log("div元素被点击2")
}

const divEl = document.querySelector(".box")

// DOM0
divEl.onclick = function() {
  console.log("div元素被点击3")
}

// DOM2
divEl.addEventListener("click", () => {
  console.log("div元素被点击4")
})
divEl.addEventListener("click", () => {
  console.log("div元素被点击5")
})
divEl.addEventListener("click", () => {
  console.log("div元素被点击6")
})

事件冒泡和事件捕获

我们会发现默认情况下事件是从最内层的span向外依次传递的顺序,这个顺序我们称之为事件冒泡(Event

Bubble)。

事实上,还有另外一种监听事件流的方式就是从外层到内层(body -> span),这种称之为事件捕获(Event

Capture);

为什么会产生两种不同的处理流呢?

  • 这是因为早期浏览器开发时,不管是IE还是Netscape公司都发现了这个问题,但是他们采用了完全相反的事件流来对事件进行了传递;
  • IE采用了事件冒泡的方式,Netscape采用了事件捕获的方式;
<!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>
    body {
      background-color: yellow;
    }

    .container {
      width: 200px;
      height: 200px;
      background-color: red;
      color: #fff;
    }

    .span {
      width: 100px;
      height: 100px;
      display: inline-block;
      background-color: blue;
      color: #fff;
    }
  </style>
</head>
<body>
  <div class="container">
    div元素
    <span class="span">span元素</span>
  </div>
</body>
</html>

const spanEl = document.querySelector(".span")
const divEl = document.querySelector(".container")

spanEl.addEventListener("click", () => {
  console.log("事件冒泡:span元素被点击了")
})

divEl.addEventListener("click", () => {
  console.log("事件冒泡:div元素被点击了")
})

document.body.addEventListener("click", () => {
  console.log("事件冒泡:body元素被点击了")
})

// 再次监听
spanEl.addEventListener("click", (event) => {
  console.log("事件捕获:span元素被点击了")
  event.stopPropagation()
}, true)

divEl.addEventListener("click", () => {
  console.log("事件捕获:div元素被点击了")
}, true)

document.body.addEventListener("click", (event) => {
  console.log("事件捕获:body元素被点击了")
}, true)

冒泡和捕获的顺序

如果我们同时有事件冒泡和时间捕获的监听,那么会优先监听到事件捕获的:

事件对象event

当一个事件发生时,就会有和这个事件相关的很多信息:

  • 比如事件的类型是什么,你点击的是哪一个元素,点击的位置是哪里等等相关的信息;
  • 那么这些信息会被封装到一个Event对象中;
  • 该对象给我们提供了想要的一些属性,以及可以通过该对象进行某些操作;

常见的属性:

  • type:事件的类型;
  • target:当前事件发生的元素;
  • currentTarget:当前处理事件的元素;
  • offsetX、offsetY:点击元素的位置;

常见的方法:

  • preventDefault:取消事件的默认行为;
  • stopPropagation:阻止事件的进一步传递;
const spanEl = document.querySelector(".span")

spanEl.addEventListener("click", (event) => {
  console.log("span元素被点击:", event)
  console.log("事件的类型:", event.type)
  console.log("事件的元素:", event.target, event.currentTarget)
  console.log("事件发生的位置:", event.offsetX, event.offsetY)
})

const divEl = document.querySelector(".container")
divEl.addEventListener("click", (event) => {
  console.log("div元素被点击:", event.target, event.currentTarget)
})

// 常见的方法
// preventDefault
const aEl = document.querySelector("a")
aEl.addEventListener("click", (event) => {
  event.preventDefault()
})

// stopPropagation

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/378723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpreadJS 16.0 中文版在线电子表设计预览EXCEL-Crack

SpreadJS 纯前端表格控件 - V16.0 新特性--内容摘自互联网 新文件结构是 SpreadJS 近几个版本中最为重要的架构级更新。这种新文件结构可以大大提高导入大型 Excel 文件的性能&#xff0c;同时在保存时创建更小、优化更好的文件。 在 V15.0 及更早的版本中&#xff0c;Spread…

android事件分发机制源码分析

没什么用的前言责任链设计模式流程图源码分析 没什么用的前言 事件分发机制是面试中一道必问的题目&#xff0c;而我的应对方式则是&#xff0c;在网络上找一些博客看看&#xff0c;然后做一些笔记&#xff0c;最后在面试时将我自己记住的内容说出来。这种方式本身没有太大的…

Editor工具开发实用篇:EditorGUI/EditorGUILayout的区别和EditorGUILayout的方法介绍

目录 一&#xff1a;EditorGUI和EditorGUILayout区别 二&#xff1a;EditorGUILayout 1.EditorGUILayout.BeginFadeGroup(float value); 2.EditorGUILayout.BeginHorizontal EditorGUILayout.BeginVertical 3.EditorGUILayout.BeginScrollView 4.EditorGUILayout.BeginT…

携手中国联通丨美格智能成为中国联通物联网产业联盟苏州分联盟副理事长单位

2月24日&#xff0c;联通数科物联网2023年巡展活动首场——中国联通物联网生态合作伙伴大会暨中国联通物联网产业联盟苏州分联盟成立仪式在苏州成功举办。本次活动由联通数字科技有限公司、中国联通物联网产业联盟联合主办&#xff0c;江苏省物联网服务协会指导&#xff0c;中国…

MySQL运维篇之日志

01、日志 1.1、错误日志 错误日志是MySQL中最重要的日志之一&#xff0c;它记录了当mysqld启动和停止时&#xff0c;以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时&#xff0c;建议首先查看此日志。 该日志是默认开启的&…

微服务之Nacos注册与配置

&#x1f3e0;个人主页&#xff1a;阿杰的博客 &#x1f4aa;个人简介&#xff1a;大家好&#xff0c;我是阿杰&#xff0c;一个正在努力让自己变得更好的男人&#x1f468; 目前状况&#x1f389;&#xff1a;24届毕业生&#xff0c;奋斗在找实习的路上&#x1f31f; &#x1…

短视频美颜sdk人脸编辑技术详解、美颜sdk代码分析

短视频美颜sdk中人脸编辑技术可以将人像风格进行转变&#xff0c;小编认为这也是未来的美颜sdk的一个重要发展方向&#xff0c;下文小编将为大家讲解一下短视频美颜sdk中人脸编辑的关键点。 一、人脸编辑的细分关键点 1、年龄 通过更改人脸的年龄属性&#xff0c;可用于模仿人…

「TCG 规范解读」TCG 软件栈 TSS (下)

可信计算组织(Ttrusted Computing Group,TCG)是一个非盈利的工业标准组织,它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立,并采纳了由可信计算平台联盟(the Trusted Computing Platform Alliance,TCPA)所开发的规范。现在的规范都不是最终稿,都…

【Redis】Redis线程IO模型与基于文件的网络通信模型(Redis专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

Unity 渲染顺序

Unity中的渲染顺序自上而下大致分为三层渲染优先级 Camera depth > Sorting Layer > Order in Layer > RenderQueueCamera depth:越小越优先&#xff08;大的显示在小的前面&#xff09;如图&#xff1a;尽管Sphere距离摄像机较远&#xff0c;但由于Camera_Sphere dep…

Linux 常用 API 函数

文章目录1. 系统调用与库函数1.1 什么是系统调用1.2 系统调用的实现1.3 系统调用和库函数的区别2. 虚拟内存空间3. 错误处理函数4. C 库中 IO 函数工作流程5. 文件描述符6. 常用文件 IO 函数6.1 open 函数6.2 close 函数6.3 write 函数6.4 read 函数6.5 lseek 函数7. 文件操作相…

算法笔记(十六)—— 有序表(红黑树,AVL树,Size-balance树,跳表),一文搞定!

有序表所有的操作都是O(logN)级别&#xff08;红黑树&#xff0c;AVL树&#xff0c;Size-balance树&#xff0c;跳表&#xff09;。 红黑树&#xff0c;AVL树&#xff0c;Size-balance树都属于平衡搜索二叉树&#xff08;BST&#xff09;。 搜索二叉书&#xff08;不保证平衡性…

OSPF -- (开放式最短路径优先协议)(公共协议)

OSPF -- &#xff08;开放式最短路径优先协议&#xff09;&#xff08;公共协议&#xff09; 1、属性&#xff1a;无类别链路状态IGP协议 无类别&#xff1a;更新携带精确掩码 链路状态&#xff1a;共享拓扑&#xff08;共享LSA&#xff09;本地计算路由IGP&#xff1a; 基于…

EasyExcel

文章目录&#x1f68f; EasyExcel&#x1f680; 一、初识EasyExcel&#x1f6ac; 1、Apache POI&#x1f6ad; 1.1 学习使用成本较高&#x1f6ad; 1.2 POI的内存消耗较大&#x1f6ad; 1.3 特点&#x1f6ac; 2、EasyExcel&#x1f6ad; 2.1 重写了POI对07版Excel的解析&#…

Nginx学习整理

Nginx学习第一章 Nginx概述1.1、Nginx概述1.2、Nginx官网1.3、Nginx用处第二章 Nginx单实例安装2.1、环境说明2.2、安装依赖2.3、Nginx下载2.4、Nginx解压2.5、Nginx安装2.6、Nginx命令2.7、开放防火墙2.8、启动后效果第三章 Nginx正向代理、反向代理3.1、概述3.2、反向代理配置…

大数据|Hadoop系统

目录 &#x1f4da;Hadoop介绍 &#x1f4da;Hadoop优点 &#x1f4da;Hadoop的体系结构 &#x1f430;HDFS的体系结构 &#x1f430;MapReduce的体系结构 &#x1f430;HDFS和MapReduce的协同作用 &#x1f4da;Hadoop与分布式开发 &#x1f430;MapReduce计算模型 &a…

【让面试官吃惊的回答:HTTP中GET和POST请求的区别你知道吗?】

一.知识回顾 之前我们一起学习了HTTP1.0、HTTP1.1、HTTP2.0协议之前的区别、以及URL地址栏中输入网址到页面展示的全过程&&DNS域名解析的过程、HTTP协议基本概念以及通信过程、HTTPS基本概念、SSL加密原理、通信过程、中间人攻击问题、HTTP协议和HTTPS协议区别、HTTP协…

Python - Opencv应用实例之CT图像检测边缘和内部缺陷

Python - Opencv应用实例之CT图像检测边缘和内部缺陷 将传统图像处理处理算法应用于CT图像的边缘检测和缺陷检测,想要实现效果如下: 关于图像处理算法,主要涉及的有:灰度、阈值化、边缘或角点等特征提取、灰度相似度变换,主要偏向于一些2D的几何变换、涉及图像矩阵的一些统…

使用ChIPSeeker进行ChIP-seq, ATAC-seq,cuttag等富集峰的基因组注释

二代测序产生的数据类型 常规的下一代高通量测序&#xff08;next generation sequencing, NGS&#xff09;实验通常产生大量短片段(reads)&#xff0c;通常我们需要将这些reads比对到参考基因组/转录组上&#xff0c;即将它们置于生物学上有意义的基因背景下&#xff0c;才能…

《MySql学习》 Select 查询语句慢的非性能原因

一.查询被阻塞 A会话执行 查询操作&#xff0c;长时间没有返回信息,此时我们就可以去排查一下是否是被阻塞了 select * from words 被阻塞的原因有很多&#xff0c;首先列举第一种情况 1.等MDL锁 当我们执行DDL语句时&#xff0c;会自动给表加上MDL写锁。当执行DML和DQL时&…