14. 文档对象模型
打开网页时,浏览器会检索网页的 HTML 文本并对其进行解析,就像第 12 章中的解析器解析程序一样。浏览器会建立一个文档结构模型,并使用该模型在屏幕上绘制页面。这种文档表示法是 JavaScript 程序在沙盒中的玩具之一。它是一种可以读取或修改的数据结构。它就像一个实时数据结构:当它被修改时,屏幕上的页面也会随之更新以反映变化。
文件结构
你可以把 HTML 文档想象成一组嵌套的方框。<body>和</body>等标签包含其他标签,而这些标签又包含其他标签或文本。下面是上一章的示例文档:
该页面的结构如下:
浏览器用来表示文档的数据结构就是这种形状。每个方框都有一个对象,我们可以通过与该对象交互来了解它所代表的 HTML 标记以及它包含的方框和文本。这种表示方法称为文档对象模型,简称 DOM。
通过全局绑定文档,我们可以访问这些对象。它的 documentElement 属性指的是代表 <html> 标记的对象。由于每个 HTML 文档都有 head 和 body,因此它也有指向这些元素的 head 和 body 属性。
树
回想一下第 12 章中的语法树。它们的结构与浏览器文档的结构极为相似。每个节点都可以指向其他节点(子节点),而子节点又可以有自己的子节点。这种形状是典型的嵌套结构,其中的元素可以包含与自身相似的子元素。
当数据结构具有分支结构、无循环(节点不得直接或间接包含自身)和单一、定义明确的根时,我们就称其为树。在 DOM 中,document.documentElement 就是根节点。树在计算机科学中经常出现。除了表示 HTML 文档或程序等递归结构外,树还经常用于维护分类数据集,因为在树中查找或插入元素通常比在平面数组中更有效率。
典型的树状结构有不同类型的节点。Egg 语言的语法树有标识符、值和应用节点。应用程序节点可能有子节点,而标识符和值是叶子,或者说是没有子节点的节点。DOM 也是如此。代表 HTML 标记的元素节点决定了文档的结构。这些节点可以有子节点。document.body 就是这样一个节点。其中一些子节点可以是叶子节点,如文本片段或注释节点。
每个 DOM 节点对象都有一个 nodeType 属性,其中包含一个标识节点类型的代码(数字)。元素的代码为 1,也定义为常量属性 Node.ELEMENT_NODE。文本节点代表文档中的一段文本,代码为 3(Node.TEXT_NODE)。注释的代码为 8(Node.COMMENT_NODE)。
另一种可视化文档树的方法如下:
叶子是文本节点,箭头表示节点之间的父子关系。
标准
使用隐晦的数字代码来表示节点类型并不像 JavaScript 所做的那样。在本章后面的内容中,我们将看到 DOM 界面的其他部分也让人感觉繁琐和陌生。这是因为 DOM 界面并不只是为 JavaScript 设计的。相反,它试图成为一个语言中立的界面,可以在其他系统中使用,不仅适用于 HTML,也适用于 XML,后者是一种具有类似 HTML 语法的通用数据格式。这是令人遗憾的。标准往往是有用的。但在这种情况下,其优势(跨语言一致性)并不那么引人注目。与跨语言的熟悉界面相比,拥有一个与你正在使用的语言适当整合的界面会为你节省更多的时间。以 DOM 中元素节点所具有的 childNodes 属性为例,就可以说明这种整合不佳的情况。该属性包含一个类似数组的对象,具有长度属性和用数字标注的属性,用于访问子节点。但它是 NodeList 类型的一个实例,而不是一个真正的数组,因此它没有 slice 和 map 等方法。
还有一些问题是由于设计不当造成的。例如,创建一个新节点后,无法立即为其添加子节点或属性。相反,您必须首先创建它,然后使用副作用逐个添加子节点和属性。与 DOM 进行大量交互的代码往往会变得冗长、重复和难看。但这些缺陷并不是致命的。由于 JavaScript 允许我们创建自己的抽象,因此可以设计出更好的方法来表达我们正在执行的操作。许多用于浏览器编程的库都带有这样的工具。
在树上移动
DOM 节点包含大量指向附近其他节点的链接。下图对此进行了说明:
虽然图中只显示了每种类型的一个链接,但每个节点都有一个 parentNode 属性,指向它所属的节点(如果有的话)。同样,每个元素节点(节点类型 1)都有一个子节点(childNodes)属性,指向一个包含其子节点的数组对象。
理论上,只需使用这些父节点和子节点链接,你就可以在树中任意移动。但 JavaScript 还提供了一些额外的便利链接。firstChild 和 lastChild 属性指向第一个和最后一个子元素,如果节点没有子元素,则其值为空。同样,previousSibling 和 nextSibling 属性指向相邻节点,即在节点本身之前或之后出现的具有相同父节点的节点。对于第一个子节点,previousSibling 的值为空,而对于最后一个子节点,nextSibling 的值为空。
还有一个 children 属性,它与 childNodes 类似,但只包含元素(类型 1)的子节点,不包含其他类型的子节点。当你对文本节点不感兴趣时,这可能会很有用。
在处理像这样的嵌套数据结构时,递归函数通常很有用。下面的函数会扫描文档,查找包含给定字符串的文本节点,找到后返回 true:
文本节点的 nodeValue 属性包含它所代表的文本字符串。
查找元素
在父节点、子节点和同级节点之间浏览这些链接通常很有用。但是,如果我们想找到文档中的一个特定节点,那么从 document.body 开始并沿着固定的属性路径找到它就不是一个好主意了。这样做会在我们的程序中加入对文档精确结构的假设--而这种结构可能是你以后想要改变的。另一个复杂因素是,即使在节点之间的空白处也会创建文本节点。示例文档的 <body> 标记不仅有三个子节点(<h1> 和两个 <p> 元素),而且有七个:这三个子节点,加上它们之前、之后和之间的空格。
如果我们想获取该文档中链接的 href 属性,就不能说 “获取文档 body 第六个子元素的第二个子元素 ”这样的话。如果我们能说 “获取文档中的第一个链接 ”就更好了。我们可以这样做。
所有元素节点都有一个 getElementsByTagName 方法,该方法会收集所有带有给定标记名的元素,这些元素都是该节点的后代(直接或间接子节点),并以数组对象的形式返回。
要查找特定的单个节点,可以给它一个 id 属性,然后使用 document.getElementById 代替。
第三个类似的方法是 getElementsByClassName,与 getElementsByTagName 一样,它也是通过搜索元素节点的内容,检索所有在其 class 属性中包含给定字符串的元素。
改变文档
DOM 数据结构的几乎所有内容都可以更改。文档树的形状可以通过改变父子关系来修改。节点有一个 remove 方法,可以将节点从当前父节点中移除。要为元素节点添加子节点,我们可以使用 appendChild(将其放在子节点列表的末尾)或 insertBefore(将作为第一个参数的节点插入到作为第二个参数的节点之前)。
一个节点在文档中只能存在于一个位置。因此,在段落一前面插入段落三,将首先从文档末尾移除该段落,然后在段落一前面插入该段落,结果是三/一/二。所有在某处插入节点的操作都会产生副作用,导致节点从其当前位置(如果有的话)移除。
replaceChild 方法用于用另一个节点替换一个子节点。它需要两个节点作为参数:一个新节点和要替换的节点。被替换的节点必须是调用该方法的元素的子节点。请注意,replaceChild 和 insertBefore 方法的第一个参数都是新节点。
创建节点
假设我们要编写一个脚本,用图片 alt 属性中的文本替换文档中的所有图片(<img> 标记)。这不仅需要删除图像,还需要添加一个新的文本节点来替换它们。
如果给定一个字符串,createTextNode 将为我们提供一个文本节点,我们可以将其插入文档,使其显示在屏幕上。遍历图像的循环从列表末尾开始。这是必要的,因为由 getElementsByTagName 等方法(或 childNodes 等属性)返回的节点列表是实时的。也就是说,它会随着文档的变化而更新。如果我们从头开始,移除第一张图片会导致列表丢失第一个元素,这样当循环第二次重复时,当 i 为 1 时,循环就会停止,因为此时集合的长度也是 1。如果你想要一个实体的节点集合,而不是一个活的节点集合,你可以通过调用 Array.from 将集合转换为一个真正的数组。
要创建元素节点,可以使用 document.createElement 方法。该方法接收一个标记名,并返回一个给定类型的新空节点。
下面的示例定义了一个实用程序 elt,它可以创建一个元素节点,并将其余参数视为该节点的子节点。该函数用于为引文添加属性。
属性
某些元素属性(如链接的 href)可以通过元素 DOM 对象上的同名属性进行访问。大多数常用的标准属性都是如此。HTML 允许在节点上设置任何属性。这非常有用,因为它可以在文档中存储额外的信息。要读取或更改自定义属性(这些属性不能作为常规对象属性使用),必须使用 getAttribute 和 setAttribute 方法。
建议在此类编造的属性名称前加上 data- 字样,以确保它们不会与任何其他属性冲突。
有一个常用的属性--class,是 JavaScript 语言中的一个关键字。由于历史原因(一些旧的 JavaScript 实现无法处理与关键字匹配的属性名称),用于访问该属性的属性称为 className。您也可以使用 getAttribute 和 setAttribute 方法访问它的真名 “class”。
布局
你可能已经注意到,不同类型的元素的布局方式是不同的。有些元素,例如段落(<p>)或标题(<h1>),占据文档的整个宽度,并且呈现在单独的行上。这些称为块级元素。其他元素,例如链接(<a>)或<strong>元素,则与周围文本在同一行呈现。这些称为行内元素。对于任何给定的文档,浏览器能够计算出一个布局,该布局为每个元素基于其类型和内容分配大小和位置。然后,这个布局用于实际绘制文档。
可以通过JavaScript访问元素的大小和位置。offsetWidth和offsetHeight属性给出元素在像素中占据的空间。像素是浏览器中的基本测量单位。它通常对应于屏幕上可以绘制的最小点,但在现代显示器上,由于可以绘制非常小的点,这可能不再成立,并且浏览器像素可能跨越多个显示点。
类似地,clientWidth和clientHeight给出元素内部空间的大小,忽略边框宽度。
要找到元素在屏幕上的精确位置,最有效的方法是使用 getBoundingClientRect 方法。该方法会返回一个包含顶部、底部、左侧和右侧属性的对象,表示元素两侧相对于屏幕左上方的像素位置。如果需要相对于整个文档的像素位置,则必须添加当前的滚动位置,这可以在 pageXOffset 和 pageYOffset 绑定中找到。
排版文档是一项相当繁重的工作。为了提高速度,每次更改文档时,浏览器引擎都不会立即重新布局,而是尽可能等待一段时间后再重新布局。当更改文档的 JavaScript 程序运行完毕后,浏览器必须计算出新的布局,才能将更改后的文档绘制到屏幕上。当程序通过读取偏移高度(offsetHeight)等属性或调用 getBoundingClientRect 来询问某些内容的位置或大小时,提供这些信息也需要计算布局。如果程序在读取 DOM 布局信息和更改 DOM 之间反复交替,就必须进行大量的布局计算,因此运行速度会非常慢。下面的代码就是一个例子。它包含两个不同的程序,分别建立一行 2000 像素宽的 X 字符,并测量每个程序所需的时间。
样式
我们看到不同的 HTML 元素以不同的方式绘制。有些元素以块级方式显示,而其他元素则是行内显示。有些元素还添加了样式——例如,<strong> 使其内容变为粗体,而 <a> 标签则使文本变为蓝色并加下划线。<img> 标签显示图像的方式或 <a> 标签在点击时跟随链接的方式与元素类型密切相关。但是,我们可以更改与元素关联的样式,例如文本颜色或下划线。以下是一个使用 style 属性的示例:
一个样式属性可以包含一个或多个声明,即一个属性(如颜色),后面跟一个冒号和一个值(如绿色)。如果有多个声明,必须用分号隔开,如:
文档的很多方面都会受到样式的影响。例如,显示属性可以控制一个元素是显示为块元素还是内联元素。
由于块元素不会与周围的文本同列显示,因此块标签将在自己的行中结束。最后一个标签是完全不显示--display: none 可以防止元素显示在屏幕上。这是一种隐藏元素的方法。这通常比将元素从文档中完全删除要好,因为这样可以方便以后再次显示。
JavaScript 代码可以通过元素的样式属性直接操作元素的样式。该属性包含一个对象,该对象具有所有可能的样式属性。这些属性的值都是字符串,我们可以通过写入字符串来改变元素样式的某个特定方面。
有些样式属性名包含连字符,如 font-family。由于在 JavaScript 中使用此类属性名比较麻烦(必须使用 style[“font-family”]),因此样式对象中的此类属性名都去掉了连字符,并将后面的字母大写(style.fontFamily)。
级联样式
HTML 的样式系统称为 CSS,即级联样式表。样式表是文档中元素样式的一组规则。它可以在 <style> 标签中给出。
名称中的“层叠”指的是多个此类规则被组合在一起,以产生元素的最终样式。在这个例子中,<strong> 标签的默认样式(使其字体加粗)被 <style> 标签中的规则覆盖,该规则添加了字体样式和颜色。当多个规则为同一属性定义值时,最近读取的规则具有更高的优先级并胜出(就近原则)。例如,如果 <style> 标签中的规则包含 font-weight: normal,与默认的 font-weight 规则相矛盾,那么文本将是正常的,而不是粗体。直接应用于节点的 style 属性中的样式具有最高优先级,并始终胜出。
在 CSS 规则中,可以定位除标签名以外的其他内容。针对 .abc 的规则适用于所有类属性中包含“abc”的元素。针对 #xyz 的规则适用于 id 属性为“xyz”的元素(在文档中应是唯一的)。
优先级规则优先考虑最近定义的规则,仅在规则具有相同的特异性时适用。规则的特异性是衡量它描述匹配元素的精确程度,取决于所需元素方面的数量和种类(标签、类或 ID)。例如,针对 p.a 的规则比针对 p 或仅 .a 的规则更具特异性,因此会优先于它们。表示法 p > a {…} 将指定的样式应用于所有直接子元素为 <p> 标签的 <a> 标签。同样,p a {…} 将应用于所有位于 <p> 标签内部的 <a> 标签,无论它们是直接子元素还是间接子元素。
查询选择器
在本书中,我们不会经常使用样式表。了解样式表对在浏览器中编程很有帮助,但它们非常复杂,需要单独写一本书。我介绍选择器语法--样式表中用于确定一组样式适用于哪些元素的符号--的主要原因是,我们可以使用相同的迷你语言作为查找 DOM 元素的有效方法。
querySelectorAll 方法既定义在文档对象上,也定义在元素节点上,它接收一个选择器字符串,并返回一个包含所有匹配元素的 NodeList。
与 getElementsByTagName 等方法不同,querySelectorAll 返回的对象不是实时对象。当你更改文档时,它不会改变。不过,它仍然不是一个真正的数组,所以如果你想把它当作一个数组,就需要调用 Array.from。querySelector 方法(没有 All 部分)的工作方式与此类似。如果你想要特定的单个元素,这个方法就很有用。它只会返回第一个匹配的元素,如果没有匹配的元素,则返回空值。
定位和动画
position 样式属性以一种强大的方式影响布局。它的默认值为static,这意味着元素位于文档中的正常位置。当设置为relative时,元素仍占用文档中的空间,但现在可以使用top和left样式属性将其相对于正常位置移动。当 position 设置为absolute位置时,该元素将从文档的正常流程中移除,也就是说,它不再占用空间,并可能与其他元素重叠。它的top和left属性可用于将其相对于position属性不是static的最近包围元素的左上角进行绝对定位,如果没有这样的包围元素,则可将其相对于文档进行绝对定位。
我们可以用它来创建动画。下面的文档显示了一幅在椭圆形中移动的猫的图片:
我们的图片在页面上居中,位置为相对位置。我们将反复更新图片的顶部和左侧样式,以移动图片。只要浏览器准备好重新绘制屏幕,脚本就会使用 requestAnimationFrame 调度 animate 函数运行。动画函数本身会再次调用 requestAnimationFrame 来安排下一次更新。当浏览器窗口(或标签页)处于活动状态时,这将导致更新以大约每秒 60 次的速度进行,从而产生好看的动画。
如果我们只是循环更新 DOM,页面就会冻结,屏幕上也不会显示任何内容。浏览器不会在 JavaScript 程序运行时更新显示内容,也不允许与页面进行任何交互。这就是我们需要 requestAnimationFrame 的原因--它让浏览器知道我们暂时完成了任务,它可以继续做浏览器要做的事情,例如更新屏幕和响应用户操作。
动画函数的参数是当前时间。为确保猫每毫秒的运动稳定,它将角度变化的速度建立在当前时间与函数上次运行时间之差的基础上。如果每步只移动固定的角度,那么当同一台电脑上运行的另一项繁重任务导致函数无法运行几分之一秒时,运动就会出现停顿。
圆周运动是通过三角函数 Math.cos 和 Math.sin 完成的。对于不熟悉这两个函数的读者,我将简要介绍它们,因为我们在本书中偶尔会用到它们。
Math.cos 和 Math.sin 可用于查找位于半径为 1 的点(0,0)周围圆上的点。这两个函数都将其参数解释为圆上的位置,0 表示圆最右边的点,顺时针方向直到 2π(约 6.28)绕完整个圆为止。Math.cos 可以告诉您给定位置对应点的 x 坐标,Math.sin 可以得出 y 坐标。位置(或角度)大于 2π 或小于 0 都是有效的--旋转重复进行,因此 a+2π 指的是与 a 相同的角度。这种测量角度的单位称为弧度--一整圈是 2π 弧度,类似于用度数测量时的 360 度。常数 π 在 JavaScript 中可以用 Math.PI 表示。
猫动画代码为动画的当前角度保留了一个计数器 angle,并在每次调用 animate 函数时递增。然后,它就可以使用这个角度来计算图像元素的当前位置。顶部样式用 Math.sin 计算,然后乘以 20,即我们椭圆的垂直半径。左侧样式基于 Math.cos 并乘以 200,因此椭圆的宽度远大于高度。
请注意,样式通常需要单位。在这种情况下,我们必须在数字后面加上 “px”,告诉浏览器我们是以像素为单位(而不是厘米、ems 或其他单位)。这一点很容易忘记。使用不带单位的数字会导致您的样式被忽略,除非该数字为 0,这意味着无论使用什么单位都是一样的。
总结
JavaScript 程序可以通过一个名为 DOM 的数据结构来检查和干扰浏览器正在显示的文档。这个数据结构代表了浏览器的文档模型,JavaScript 程序可以通过修改它来改变可见文档。
DOM 的组织结构就像一棵树,其中的元素根据文档的结构分层排列。代表元素的对象具有父节点(parentNode)和子节点(childNodes)等属性,可用于在树中导航。
文档的显示方式可以受到样式的影响,既可以直接将样式附加到节点上,也可以定义与某些节点匹配的规则。有许多不同的样式属性,如颜色或显示。JavaScript 代码可以直接通过元素的样式属性来操作元素的样式。
相关文章:

14. 文档对象模型
打开网页时,浏览器会检索网页的 HTML 文本并对其进行解析,就像第 12 章中的解析器解析程序一样。浏览器会建立一个文档结构模型,并使用该模型在屏幕上绘制页面。这种文档表示法是 JavaScript 程序在沙盒中的玩具之一。它是一种可以读取或修改…...

【计网】【计网】从零开始学习http协议 ---理解http重定向和请求方法
去光荣地受伤, 去勇敢地痊愈自己。 --- 简嫃 《水问》--- 从零开始学习http协议 1 知识回顾2 认识网络重定向3 http请求方法3.1 http常见请求方法3.2 postman工具进行请求3.3 处理GET和POST参数 1 知识回顾 前面两篇文章中我们学习并实现了http协议下的请求与应…...

yolov8/9/10/11模型在中医舌苔分类识别中的应用【代码+数据集+python环境+GUI系统】
yolov8、9、10、11模型在中医舌苔分类识别中的应用【代码数据集python环境GUI系统】 背景意义 目前随着人们生活水平的不断提高,对于中医主张的理念越来越认可,对中医的需求也越来越多。 传统中医的舌诊主要依赖于医生的肉眼观察,仅仅通过这…...

k8s部署安装
k8s部署安装 一 K8s集群环境搭建1.1 k8s中容器的管理方式1.2 k8s集群部署1.2.1 k8s环境部署说明1.2.2 k8s集群环境初始化1.2.2.1 所有节点禁用swap和本地解析1.2.2.2 所有节点安装docker1.2.2.3.所有节点设定docker的资源管理模式为systemd1.2.2.4.所有阶段复制harbor仓库中的证…...

gpt为什么可以依据上下文来回答问题,依据的是什么原理
GPT 可以依据上下文回答问题,主要依据以下几个原理: Transformer 架构: 并行计算与长距离依赖处理:Transformer 架构摒弃了传统的递归神经网络和长短时记忆网络的序列依赖处理方式,具有并行计算的能力。它可以同时处理…...

2023 CCPC哈尔滨 报告
比赛链接:Dashboard - 10.6组队训练赛-2023CCPC哈尔滨站 - Codeforceshttps://codeforces.com/group/w6iGs8kreW/contest/552949 做题数:3 题 三题都是队友写的。所以来补一下 B L J。 B题: B. Memory Little G used to be a participant …...

基于深度学习的手术中的增强现实导航
基于深度学习的手术中的增强现实(AR)导航技术是一种结合了先进的计算机视觉算法、深度学习模型与增强现实技术的创新应用。其主要目的是为外科手术提供实时的、精确的手术指导,帮助医生在复杂的手术过程中更好地理解患者的解剖结构࿰…...

输电线路缺陷图像检测数据集,导线散股,塔材锈蚀两类,分别为581张和1407张,标注为xml和txt格式 1988张
输电线路缺陷图像检测数据集,分为导线散股,塔材锈蚀两类,分别为581张和1407张,标注为xml和txt格式 数据集名称 输电线路缺陷图像检测数据集 (Transmission Line Defect Detection Dataset) 数据集概述 该数据集是一个专门用于训…...

百度飞桨(paddlepaddle)安装
百度飞桨(paddlepaddle)安装 Anaconda升级 打开 Anaconda Prompt (或者 Mac 下的终端),键入: conda upgrade --all pip 安装 python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/s…...

≌图概念凸显有长度不同的射线
黄小宁 【摘要】自有射线概念后的2300年里一直无人能知有长度不同的射线、无人能知有互不≌的射线,从而使数学一直有几何“常识”:任何射线都没有长度差别。保距变换和≌图概念使人能一下子看到有长度不同的射线。 变量x所取各数也均由x代表,…...

解决Nginx出现“Too many open files”的问题
解决Nginx出现“Too many open files”的问题 在那个不经意的瞬间,我感到一阵莫名的恍惚。同事突然提出要看我的手机,她的目光落在了我那泛黄的手机壳上。出乎意料地,她开始细心地擦拭,从内到外,动作轻柔而专注。那一刻…...

webGL进阶(一)多重纹理效果
效果: 代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&q…...

flink-jdbc-driver
Flink JDBC 驱动程序是一个 Java 库,使客户端能够通过 SQL 网关将 Flink SQL 发送到 Flink 集群。 首先启动:1.flink集群,随意任何集群。 2.启动flink-sql-gateway: sql-gateway.sh start -Dsql-gateway.endpoint.rest.addresslo…...

快速的配置Prettier,让代码更整洁
快速的配置Prettier,让代码更整洁 一个人一个代码风格,先抛开语法的使用不谈,加不加空格、加不加分号也是萝卜白菜各有所爱,那怎么统一我们的代码格式呢 prettier 就是为我们解决这个问题的 1. 如何制定我们的代码风格 我们可以在…...

JavaEE: HTTPS的魅力与优势揭秘
文章目录 HTTPSHTTPS 是什么HTTPS 基本工作过程Fiddle 等抓包工具,为啥能解析 HTTPS 的数据? HTTPS HTTPS 是什么 HTTPS 是一个应用层协议,是在 HTTP 协议的基础上引入了一个加密层. 几个核心概念: 明文: 要传输的原始数据.密文: 把明文进行加密之后得到一个让别人不能理解…...

软件设计师——系统基础开发
📔个人主页📚:秋邱-CSDN博客☀️专属专栏✨:软考——软件设计师🏅往期回顾🏆:软件设计师——信息安全🌟其他专栏🌟:C语言_秋邱 一、软件工程概述 1.1、考…...

架构设计笔记-7-系统架构设计基础知识
目录 知识要点 单选 案例分析 1.质量属性 / 管道过滤器 / 数据仓库风格 2.面向对象风格 / 控制环路风格 3.软件架构风格 / 架构风格选择 4.体系结构方案对比 5.面向对象风格 / 基于规则风格 6.解释器风格 / 管道过滤器风格 7.面向对象风格 / 解释器风格 8.软件架构复…...

跨平台应用程序本地化过程的特点
跨平台应用程序本地化不仅仅是将单词从一种语言翻译成另一种语言。这是关于调整应用程序,使其无缝融入全球用户的不同文化和语言环境,无论他们使用的是哪种设备或平台。这个过程对于跨平台应用程序来说尤其复杂,它们需要在多个操作系统和设备…...

C++面试速通宝典——9
170. 简述数组和指针的区别? 答:数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。 1. 修改内容上的区别 char a[] “hello”; a[0] ‘X’; char * p …...

阿里巴巴商品详情API返回值:电商行业发展的新动力
阿里巴巴的商品详情API在电商行业中扮演着至关重要的角色,它不仅为商家和消费者提供了丰富的产品信息,还推动了电商行业的进一步发展和创新。通过API接口,开发者可以获取商品的详细信息,如标题、价格、库存、评价等,进…...

php的urlencode和rawurlencode区别
urlencode和rawurlencode都是用于对URL进行编码的函数,但它们在处理方式和应用场景上存在明显的区别。以下是关于这两个函数的详细比较: 一、定义与标准 urlencode:基于rawurlencode标准,但有略微的不同,它定义在rfc…...

LeetCode讲解篇之322. 零钱兑换
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们可以使用动态规划解决这道题,我们首先定义一个数组,数组中第i个元素表示组成金额 i 的最少硬币个数 我们遍历数组的1 ~ amount号位置,对coins进行遍历,查找选…...

猴子吃桃-C语言
1.问题: 猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。 第二天早上又将剩下的桃子吃掉一半,又多吃一个。以后每天早上都吃了前一天剩下的一半零一个。 到第N天早上想再吃时,见只剩下一个…...

【C++】单例模式「详尽版」
欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 文章目录 什么是单例模式如何实现单例模式饿汉模式和懒汉模式饿汉模式懒汉模式饿汉模式和懒汉模式的优缺点1.饿汉模式的优缺点2.懒汉模式的优缺点 什么是单例模式 C单例模式是一种非常重要的设计模式…...

MongoDB集群模式详解及应用实战
目录 本节课内容: 集群搭建 1.创建3个目录: 2.编辑配置文件 编辑 3.启动: 4.看看: 5.另外,两个如上1,2,3步骤操作 ,但是日志目录,端口什么的需要改一下即可。 …...

接着上一篇stp 实验继续
理论看上一篇,我们直接实验 首先找出root 桥 很明显 sw1 为root 桥,所谓sw1 &a…...

怎么将手机备忘录传送至电脑
在数字化时代,手机备忘录已成为我们生活中不可或缺的一部分。无论是记录购物清单、工作事项,还是灵感闪现的瞬间,手机备忘录都能随时记录下这些宝贵的信息,帮助我们防止遗忘。然而,有时候我们需要将这些备忘录内容转移…...

解决触摸屏屏幕乱动的问题:E: 无法定位软件包 libinput
在 Ubuntu 中,你可能已经有 libinput 库,它通常默认包含在系统中。如果你想使用 libinput 来管理输入设备(例如触摸屏或触摸板),通常不需要安装额外的软件包,而是直接使用系统自带的工具。 不过࿰…...

RISC-V笔记——基础
1. 前言 RISC-V旨在支持广泛的定制和专业化。RISC-V的ISA是由一个基本整型ISA和其它对基本ISA的可选扩展组成。每个整型ISA可以使用一个或多个可选的ISA扩展进行扩展。 基本整型ISA精选了最小的一组指令,这些指令足以为编译器、汇编器、链接器和操作系统提供足够的…...

「Kafka」Kafka消息可靠性和重复消费问题(五)
在 Kafka 中,实现消息的可靠性和避免重复消费是保证数据一致性和系统稳定性的关键。Kafka 提供了多种机制来实现这两个目标。 1. Kafka 消息可靠性 Kafka 的可靠性主要体现在消息的投递和存储上,以确保消息不会丢失。具体来说,有以下几个措…...