Js Dom

news/2024/11/6 11:20:32/文章来源:https://www.cnblogs.com/Mickey-7/p/18529571

DOM,全称Document Object Model,中文翻译为文档对象模型。DOM属于Web API的一部分。Web API中定义了非常多的对象,通过这些对象可以完成对网页的各种操作(添加删除元素、发送请求、操作浏览器等)

DOM中的D意为Document,即文档。所谓文档就是指整个网页,换言之,DOM是用来操作网页的。O意为Object,即对象。DOM将网页中的每一部分内容都转换为了对象,div有div的对象,input有input的对象,甚至一段文本,一段注释也有其所对应的对象。转换对象以后,我们就可以以面向对象的方式去操作网页,想要操作哪个元素就获取哪个元素的对象,然后通过调用其方法或属性完成各种操作。M意为Model,即模型。模型用来表示对象之间的关系,也就是父子元素、祖先后代、兄弟元素等,明确关系后我们便可以通过任意一个对象去获取其他的对象

网页中的各种元素(如标签、文本、属性等)被表示为对象,这些对象以树状结构组织起来,称为 DOM 树

例如,对于一个简单的 HTML 页面

Hello, World!

,其 DOM 树的根节点是html,html节点下有body子节点,body节点下又有p子节点,p节点包含文本内容 “Hello, World!”

document对象

要使用DOM来操作网页,我浏览器至少得先给我一个对象才能去完成各种操作,浏览器已经为我们提供了一个document对象,它是一个全局变量可以直接使用

<body><button id = "btn">按钮</button><script>// 通过id获取btn对象const btn = document.getElementById("btn")// 将按钮文案更改为新按钮// innerText的用于获取或者设置元素内部的文本内容btn.innerText = "新按钮"</script></body>
  • document对象表示的是整个网页
    • document对象的原型链
      HTMLDocument -> Document -> Node -> EventTarget -> Object.prototype -> null
    • 凡是在原型链上存在的对象的属性和方法都可以通过Document去调用
    • 部分属性:
      document.documentElement --> html根元素
      document.head --> head元素
      document.title --> title元素
      document.body --> body元素
      document.links --> 获取页面中所有的超链接
    • 用法大全

节点

在DOM标准下,网页中的每一个部分都会转换为对象。这些对象有一个共同的称呼——节点(Node)。一个页面将会由多个节点构成,虽然都称为节点,但是它们却有着不同的类型:文档节点、元素节点、文本节点、属性节点....

每一个节点都有其不同的作用,文档节点表示整个网页,元素节点表示某个标签,文本节点表示网页中的文本内容,属性节点表示标签中的各种属性。如果从对象的结构上来讲,这些对象都有一个共同的父类Node。总的来说,都是属于节点,但是具体类型不同

元素节点

元素节点对象(element),在网页中,每一个标签都是一个元素节点

<body><button id = "btn" class="btn-class">按钮</button><input type="radio" name="one"><script>// 通过id获取元素节点对象const btnId = document.getElementById("btn")console.log(btnId) // <button id="btn" class="btn-class">按钮</button>// 通过class获取所有符合条件的元素条件对象,返回的是一个类数组对象// 该方法返回的结果是一个实时更新的集合,当网页中新添加元素时,集合也会实时更新const btnClass = document.getElementsByClassName("btn-class")console.log(btnClass) // HTMLCollection[button#btn.btn-class, btn: button#btn.btn-class]// 根据标签名获取一组元素节点对象// 该方法返回的结果是一个实时更新的集合,当网页中新添加元素时,集合也会实时更新// document.getElementsByTagName("*") 获取页面中所有的元素const btnTag = document.getElementsByTagName("button")console.log(btnTag) // HTMLCollection[button#btn.btn-class, btn: button#btn.btn-class]// 根据name属性获取一组元素节点对象, 返回一个实时更新的集合,主要用于表单const inputName = document.getElementsByName("one")console.log(inputName) // NodeList[input]// 根据各种css选择器去页面中查询元素,会返回一个类数组(不会实时更新)const query = document.querySelectorAll(".btn-class")console.log(query) // NodeList[button#btn.btn-class]// 根据选择器去页面中查询第一个符合条件的元素,没有则返回nullconst firstQuery = document.querySelector("button")console.log(firstQuery) //  <button id="btn" class="btn-class">按钮</button>// 根据标签名创建一个元素节点对象,只是创建,未插入到网页const newTag = document.createElement("h1")console.log(newTag) // <h1></h1></script></body>
/*
通过元素节点对象获取其他节点
*/<body><div id = "box"><button id = "btn" class="btn-class">按钮</button><input type="radio" name="one"></div><button class="btn-class">按钮2</button><script>const element = document.getElementById("box")// document对象的方法元素节点对象可以同样使用,区别是在于获取的是当前对象内的指定对象// 获取element内的button对象const btn = element.getElementsByTagName("button")console.log(btn) // HTMLCollection[button#btn.btn-class, btn: button#btn.btn-class]// 获取当前元素的子节点(包含空白的子节点)const childNodes = element.childNodesconsole.log(childNodes) // NodeList(5) [text, button#btn.btn-class, text, input, text]// 获取当前元素的子元素const children = element.childrenconsole.log(children) // HTMLCollection(2)[button#btn.btn-class, input, btn: button#btn.btn-class, one: input]// 获取当前元素的第一个子元素const firstElementChild = element.firstElementChildconsole.log(firstElementChild) // <button id = "btn" class="btn-class">按钮</button>// 获取当前元素的最后一个子元素const lastElementChild = element.lastElementChildconsole.log(lastElementChild) // <input type="radio" name="one">// 获取当前元素的下一个兄弟元素const nextElementSibling = element.nextElementSiblingconsole.log(nextElementSibling) //     <button class="btn-class">按钮2</button>// 获取当前元素的前一个兄弟元素const previousElementSibling = element.previousElementSiblingconsole.log(previousElementSibling) // null// 获取当前元素的父节点const parentNode = element.parentNodeconsole.log(parentNode) // <body>...</body>// 获取当前元素的标签名const tagName = element.tagNameconsole.log(tagName) // DIV</script></body>
文本节点

在DOM中,网页中所有的文本内容都是文本节点对象,包括空文本、换行和空格

<body><div id = "box">asdasd<button id = "btn" class="btn-class">按钮</button><input type="radio" name="one"></div><button class="btn-class">按钮2</button><script>// 可以通过元素来获取其中的文本节点对象,但是我们通常不会这么做,我们可以直接通过元素去修改其中的文本const element = document.getElementById("box")const t = element.firstChildconsole.log(t) //  asdasd</script></body>

直接通过元素去修改其中的文本

<body><div id = "box">asdasd<button id = "btn" class="btn-class">按钮</button><input type="radio" name="one"></div><button class="btn-class">按钮2</button><script>const element = document.getElementById("box")// textContent获取或修改元素中的文本内容,获取的是标签中的内容,不会考虑css样式// 当字符串中有标签时,会自动对标签进行转义显示在页面,不会渲染// 如果修改会在网页直接生效console.log(element.textContent) // 获取文本:asdasd 按钮console.log(element.firstChild.textContent) // 获取element第一个子节点文本:asdasdelement.firstChild.textContent = "new t" // 将第一个文本修改为new t// innerText获取或修改元素中的文本内容,会考虑css样式,会触发网页的重排(计算CSS样式)// 当字符串中有标签时,会自动对标签进行转义显示在页面,不会渲染// 如果修改会在网页直接生效// 获取element的第一个元素子节点文本console.log(element.firstElementChild.innerText) // 按钮element.firstElementChild.innerText = "大按钮" // 修改element的第一个元素子节点文本// innerHTML获取或修改元素中的html代码,可以直接向元素中添加html代码,innerHTML插入内容时,有被xss注入的风险// 当字符串中有标签时,会在网页生效console.log(element.firstElementChild.innerHTML) // 大按钮'element.firstElementChild.innerHTML = "<h1>新大按钮</h1>" // h1效果会在网页生效</script></body>
属性节点

属性节点(Attr)在DOM也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作

<input class="admin" type="text" name="username" value="user"><input class="admin1" type="text" name="username1" value="user1"><script>const input = document.querySelector("[name=username]")const input2 = document.querySelector(".admin1")// 通过元素.属性名 可以读取、修改对应的数据console.log(input.className) // admin,读取class属性比较特殊,需要使用classNameconsole.log(input.type) // textconsole.log(input.name) // usernameinput.value = "new user" // 修改value的值为new userconsole.log(input.disabled) // false 读取一个布尔值时,会返回true或false// 通过方法读取、修改对象的属性// 读取属性console.log(input2.getAttribute("type")) // text// 修改属性,将value属性的值修改为uuuinput2.setAttribute("value","uuu")// 删除属性input2.removeAttribute("value")</script></body>

事件

事件(event)

  • 事件就是用户和页面之间发生的交互行为
    比如:点击按钮、鼠标移动、双击按钮、敲击键盘、松开按键...
  • 可以通过为事件绑定响应函数(回调函数),来完成和用户之间的交互
  • 绑定响应函数的方式:
    1.可以直接在元素的属性中设置
    2.可以通过为元素的指定属性设置回调函数的形式来绑定事件(一个事件只能绑定一个响应函数)
    3.可以通过元素addEventListener()方法来绑定事件
<body><button id="btn">点击</button><script>// 获取按钮对象const btn = document.getElementById("btn")// 为该按钮的点击事件设置响应函数,该方式一个事件只能绑定一个响应函数,如果后续重复绑定会被覆盖btn.onclick = function (){alert("onclick!!!")}// 通过addEventListener绑定事件 第一个参数是触发的事件,第二个参数是响应函数// 该方式一个事件可以绑定多个响应函数,根据绑定顺序执行btn.addEventListener("click",function (){console.log("addEventListener")})btn.addEventListener("click",function (){alert("addEventListener")})
</script></body>

文档的加载

网页是自上向下加载的,如果将js代码编写到网页的上边,js代码在执行时,网页还没有加载完毕,这时会出现无法获取到DOM对象的情况

如何解决这个问题:

1. 将script标签编写到body的最后 
2. 将代码编写到window.onload的回调函数中
3. 将代码编写到document对象的DOMContentLoaded的回调函数中(执行时机更早)
4. 将代码编写到外部的js文件中,然后以defer的形式进行引入(执行时机更早,早于DOMContentLoaded)
<script>// window.onload 事件会在窗口中的所有内容(一个网页可能有外嵌页面)加载完毕之后才触发// 窗口内容加载完之后触发响应函数执行js代码window.onload = function () {// 获取按钮对象const btn = document.getElementById("btn")btn.addEventListener("click", function () {alert("addEventListener")})}</script><body><button id="btn">点击</button></body>
    // DOMContentLoaded事件会在当前文档加载完后执行document.addEventListener("DOMContentLoaded",function (){// 获取按钮对象const btn = document.getElementById("btn")btn.addEventListener("click", function () {alert("addEventListener")})})
<!-- 引入外部js文件 -->
<!-- 如果默认引入在body上,依然会有加载时机问题 -->
<!-- defer 关键字会延迟加载,当前文档加载完再加载,解决该问题--><script defer src = "./script/index.js"></script>

DOM元素的修改

创建元素
appendChild

appendChild()是 DOM节点对象的一个方法。它的主要作用是将一个节点添加到另一个节点的子节点列表的末尾。这是一种在 HTML 文档结构中动态添加元素的方式

<body><button id="btn">按钮</button><ul id="list"><li id="one">1</li><li id="two">2</li><li id="three">3</li>
</ul></body><script>// 获取ulconst list = document.getElementById("list")// 获取按钮const  btn = document.getElementById("btn")// 点击按钮的时候触发btn.onclick = function (){// 创建一个liconst li = document.createElement("li")// li的文本li.textContent = "4"// 设置li的idli.id = "four"// 把创建的li元素添加到ul里面// appendChild把一个节点添加到另一个节点list.appendChild(li)}</script>
insertAdjacentElement

insertAdjacentElement()是js的一个 DOM 操作方法。它用于将一个指定的元素插入到另一个元素的附近特定位置

 // 点击按钮的时候触发btn.onclick = function (){// 创建一个liconst li = document.createElement("li")// li的文本li.textContent = "4"// 设置li的idli.id = "four"// 把创建的li元素添加到ul里面// 参数:1. 要添加的位置 2. 要添加的元素list.insertAdjacentElement("afterbegin",li)// beforeend 标签的最后 afterbegin 标签的开始// beforebegin 在元素的前边插入元素(兄弟元素) afterend 在元素的后边插入元素(兄弟元素)}
insertAdjacentHTML

insertAdjacentHTML()用于在指定元素的附近插入 HTML 字符串的方法。允许你将 HTML 代码片段作为字符串插入到元素的不同位置,有XSS攻击的风险

    // 点击按钮的时候触发btn.onclick = function (){// 参数:1. 要添加的位置 2. 要插入的html代码字符串list.insertAdjacentHTML("afterbegin","<li id='5'>5</li>>")// beforeend 标签的最后 afterbegin 标签的开始// beforebegin 在元素的前边插入元素(兄弟元素) afterend 在元素的后边插入元素(兄弟元素)}
替换元素
        // 获取 id=one的liconst one = document.getElementById("one")// 创建一个新的liconst newOne = document.createElement("li")newOne.textContent = "1111"newOne.id="new-one"// replaceWith 使用一个元素替换当前元素// newOne替换oneone.replaceWith(newOne)
删除元素
  const two = document.getElementById("two")// remove()方法用来删除当前元素two.remove()
取消元素的默认行为
<!--javascript:; 执行代码 但是代码是空的,即不发生任何行为操作-->
<a href="javascript:;"></a>

使用return false来取消默认行为,只在 xxx.xxx = function(){}这种形式绑定的事件中才适用

    // 响应函数function delUserInfo(){// 为所有超链接绑定了该响应函数,点击哪个链接,this就是哪个// parentNode是一个节点属性。它用于获取当前节点的父节点const tr = this.parentNode.parentNode// 获取用户昵称const userName = tr.firstElementChild.textContent// confirm()是一个浏览器提供的全局函数,用于显示一个带有 “确定” 和 “取消” 按钮的模态对话框。这个对话框用于向用户询问一个是 / 否的问题,并且等待用户做出响应if (confirm(`确认要删除${userName}吗`)){tr.remove()}// 取消默认事件return false}// 获取所有超链接const links = document.links// 为所有的链接绑定单级响应函数for (let link of links){link.onclick = delUserInfo}
节点的复制
    // 获取ul列表const list = document.getElementById("list")// 获取id为li1的元素节点const li1 = document.getElementById("li1")//  使用li1节点复制一份,赋值给newLiconst newLi = li1.cloneNode(true)newLi.id = "li2"list.appendChild(newLi)/* 使用 cloneNode() 方法对节点进行复制时,它会复制节点的所有特点包括各种属性这个方法默认只会复制当前节点,而不会复制节点的子节点可以传递一个true作为参数,这样该方法也会将元素的子节点一起复制*/

通过DOM操作css

使用style读取、修改内联样式
    // 获取box元素const box = document.getElementById("box")// 修改box的内联样式样式box.style.width = "400px"box.style.height = "400px"// 如果样式名中含有-,则需要将样式表修改为驼峰命名法,background-color --> backgroundColorbox.style.backgroundColor = "yellow"    // 读取内联样式console.log(box.style.height)
读取当前生效的样式
     // 获取box元素const box = document.getElementById("box")// getComputedStyle返回一个只读对象,这个对象中包含了当前元素所有的生效的样式,无法通过该方式修改样式// 参数:要获取样式的对象,要获取的伪元素const styleObj = box.getComputedStyle(box)// 当前生效的宽度console.log(styleObj.width)// 当前生效的高度console.log(styleObj.height)// 获取before伪元素的样式const styleObj1 = box.getComputedStyle(box,"::before")console.log(styleObj1.width)
其他读取样式的方式
    // 获取box元素const box = document.getElementById("box")//  获取元素内部的宽度和高度,包含内容区和内边距console.log(box.clientWidth)console.log(box.clientHeight)// 获取元素的可见框的大小,包含内容区、内边距和边框console.log(box.offsetWidth)console.log(box.offsetHeight)// 获取元素滚动区域的宽度和高度console.log(box.scrollWidth)console.log(box.scrollHeight)// 获取元素的定位父元素,离当前元素最近的开启了定位的祖先元素,如果所有的元素都没有开启定位则返回bodyconsole.log(box.offsetParent)// 获取元素相对于其定位父元素的偏移量console.log(box.offsetTop)console.log(box.offsetLeft)//获取 or 设置元素滚动条的偏移量console.log(box.scrollTop)console.log(box.scrollLeft)box.scrollTop = 100 // 设置偏移量
操作class修改css样式

除了直接修改样式外,也可以通过修改class属性来间接的修改样式

<style>.btn{width: 200px;}</style><script>const btn1 = document.getElementById("btn1")const btn2 = document.getElementById("btn2")// 在原先class名字的基础上 加一个btn的class// css样式中的类选择器命中设置样式btn1.className += " btn"btn2.className += " btn"</script>

通过class修改样式的好处:

         1. 可以一次性修改多个样式2. 对JS和CSS进行解耦
    const btn1 = document.getElementById("btn1")// 元素.classList 是一个对象,对象中提供了对当前元素的类的各种操作方法// 向元素中添加一个或者多个classbtn1.classList.add("btn2","btn3")// 移除元素中的一个或多个classbtn1.classList.remove("btn2")// 切换元素中的class,如果有btn2的class,则删除,如果没有,就加上btn1.classList.toggle("btn2")// 替换class,将btn1替换为btn2btn1.classList.replace("btn1","btn2")// 检查class,有该class返回true,否则falsebtn1.classList.contains("btn1")

事件对象

事件对象:

  • 事件对象是有浏览器在事件触发时所创建的对象,这个对象中封装了事件相关的各种信息

  • 通过事件对象可以获取到事件的详细信息,比如:鼠标的坐标、键盘的按键..

  • 浏览器在创建事件对象后,会将事件对象作为响应函数的参数传递,

  • 所以我们可以在事件的回调函数中定义一个形参来接收事件对象

    const box = document.getElementById("box")// 监听事件,在创建事件对象后,会将事件对象作为响应函数的参数传递,在事件的回调函数中定义一个形参来接收事件对象box.addEventListener("mousemove",event => {console.log(event) // 包含很多属性和方法的对象,具体取决于触发的事件类型console.log(event.clientX) // 获取X轴console.log(event.clientY) // 获取Y轴})box.addEventListener("click",function (event){console.log(event)})
Event对象

在DOM中存在着多种不同类型的事件对象,多种事件对象有一个共同的祖先 Event

const box = document.getElementById("box")box.addEventListener("click", event => {// 触发事件的对象console.log(event.target) // id 为box的元素// 绑定事件的对象(与事件冒泡有关),同thisconsole.log(event.currentTarget)/*- 事件的冒泡就是指事件的向上传导- 当元素上的某个事件被触发后,其祖先元素上的相同事件也会同时被触发,由里向外- 冒泡的存在大大的简化了代码的编写,但是在一些场景下我们并不希望冒泡存在,可以通过事件对象来取消冒泡- 事件的冒泡和元素的样式无关,和结构相关*/// 取消事件传导(冒泡)event.stopPropagation()//  取消默认行为event.preventDefault()})
事件委派

只绑定一次事件,即可以让所有的元素对象,包括当前和未来新建的都具有这些事件

委派就是将本该绑定给多个元素的事件,统一绑定给document然后根据判断逻辑由什么元素触发,这样可以降低代码复杂度方便维护

<body>
<button id="btn">按钮</button><ul id="list"><li><a href="#">1</a></li><li><a href="#">2</a></li><li><a href="#">3</a></li>
</ul></body><script>const list = document.getElementById("list")const btn = document.getElementById("btn")// 获取list中所有超链接const links = list.getElementsByTagName("a")//  可以将事件统一绑定给document,这样点击事件的冒泡,会导致document上的点击事件被触发//  这样只绑定一次,所有的点击都会具有这些事件document.addEventListener("click", (event) => {// 判断事件是由谁触发,event.target 是否在 links 中存在// 只有list中的超链接点击生效,如果不判断事件触发,页面所有点击效果都会生效if ([...links].includes(event.target)) {alert(event.target.textContent)}})// 点击按钮后,在ul中加一个新的libtn.addEventListener("click", () => {list.insertAdjacentHTML("beforeend", "<li><a href='#'>new</a></li>")})</script>
事件捕获

在DOM中,事件的传播可以分为三个阶段:

​ 1.捕获阶段 (由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)

​ 2.目标阶段 (触发事件的对象)

​ 3.冒泡阶段 (由目标元素向祖先元素进行事件的冒泡)

事件的捕获,指事件从外向内的传导:

  • 当前元素触发事件以后,会先从当前元素最大的祖先元素开始向当前元素进行事件的捕获
  • 冒泡是由里向外,而捕获是是由外向里
    const box = document.getElementById("box")box.addEventListener("click", event => {// eventPhase 表示事件触发的阶段console.log(event.eventPhase)// 如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true}, true)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决修改php.ini配置文件不生效的问题

公司禅道研发反馈任务创建的多了就报:Allowed memory size of 33554432 bytes exhausted (tried to alloate 3643528 bytes) in lib/base/front/front.class.php on line 1315 when visiting /index.php?m=execution&f=task&id=28;通过报错即可得知,php的memory_li…

Error:Kotlin: Module was compiled with an incompatible version of Kotlin.

idea 启动项目时报错 Error:Kotlin: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.1.16. 解决方案(windows): 1、打开Kotlin面板 路径:File -> settings -> Languages & F…

JavaScript用法

JavaScript 用法HTML 中的 Javascript 脚本代码必须位于 <script> 与 </script> 标签之间。 Javascript 脚本代码可被放置在 HTML 页面的 <body> 和 <head> 部分中。<script> 标签 如需在 HTML 页面中插入 JavaScript,请使用 <script> 标…

在vite里面,使用linaria,css样式名混淆的问题

我们项目使用css in js来实现样式,借用了一个插件linaria。但是有一个问题,就是样式名会被混淆如下解决方法是,vite配置里面加一个 就可以了,结果如下

刚毕业,去做边缘业务,还有救吗?

有一些同时拿到了多个 Offer 的同学,会纠结于如何选择。其中有一些比较共性的问题,比如 “刚毕业,去做边缘业务,会不会影响后面的人生呢?”大家好,我是程序员鱼皮。今年的秋招已经接近尾声,我陆续收到了很多小伙伴们的 Offer 报喜。有一些同时拿到了多个 Offer 的同学,…

符合ISO26262的零部件级的软件测试解决方案

引言在功能安全的开发、测试过程中概念阶段的活动一般都是由主机厂负责,而从系统开发到单元实现则是由供应商负责,对于供应商所做的一系列测试通常称为零部件级测试。根据ISO 26262功能安全标准的划分,功能安全在零部件阶段的测试包括:软件单元测试、软件集成测试、硬件集成…

惊呆:where 1=1 可能严重影响性能,差了10多倍,快去排查你的 sql

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…

鸿蒙项目实战(二):实现动态栅格布局

需求: 动态设置栅格布局子元素实现如下: 一、定义一个类,定义所有的子元素数据// 首页业务按钮可选项集合 export class HomeBussinessConfig{// 供选择的所有tab集合// 只读 静态static readonly buttons = [{title:功能一,icon:$r(app.media.icon_home_sale),},{title:功能…

Dynaseal-面向未来端侧llm agent的llm api key分发机制

为什么要有这个项目 试想一下,在未来 llm agent 在端侧全面铺开,但是目前调用大模型的方式通过了是一个拿到了就可以随便使用的 api-key?那用户岂不是从端侧的模型拿到了 api-key 就可以刷爆你的账单?!!!如果每个人的手机都跑着几个 agent,你还有一堆用户,那你服务器岂…

使用SeaTunnel从InfluxDB同步数据到Doris

本文介绍了如何使用SeaTunnel将数据从InfluxDB同步到Doris。通过SeaTunnel强大的数据集成功能,用户可以高效地将存储于InfluxDB中的时间序列数据传输至Doris,便于数据的访问与分析。版本信息: SeaTunnel 2.3.3 InfluxDB 2.7.6 Doris 2.1.3 rc09准备事项 SeaTunnel2.3.3的安装…

CMU_15445_P2_Extendible_Hash_Table

到Project2, 我们依然在处理数据库存储相关的部分, 从 Project1 中我们应该Get到两个概念:数据库底层数据操作的基本单元是 Page. buffer_pool_manager 是管理以及组织数据单元Page的工具, 在Project2的第一部分, 我们还新增了页面守护(PageGuard)的机制更加优雅的获取以及释放…

关于pacman更新时出现error: GPGME error: No data 解决方法

问题复现 基本上我隔一段时间就会出现这个问题,每一次都是在网络上寻找相关命令来解决,但是却不明白为什么会出现这个问题。 问题大概是这样的但是有一位博主详细的帮忙解答了问题,大概的意思是指:pacman 在更新数据库文件时会尝试下载每个仓库的 .db.sig 文件,这是数据库…