JS事件和DOM

1. DOM

1.1 基本概念

DOM,全称 Document Object Model,即文档对象模型。是 Web 上最常用的 API 之一,是加载在浏览器中的文档模型,可以将文档表示为节点树(或称 DOM 树),其中每个节点代表文档的一部分(例如,元素、文本字符串或注释)

它允许在浏览器中运行的代码访问文档中的每个节点并与之交互。可以创建、移动和更改节点,还可以将事件监听器添加到节点,并在特定事件发生时触发

简单来说,DOM就是JS操作网页的接口,是JS和网页之间的桥梁。

W3C官方解释:DOM是一种编程接口或平台,它允许程序或脚本(如JavaScript)动态地访问和更新文档的内容、结构和样式


1.2 DOM的作用

DOM的主要作用是将网页转为一个JS对象,从而可以用JS对网页进行各种操作,如,

1. 通过DOM,使用JS获取、修改、创建、删除文档中得元素、元素属性、文本等内容

2. 通过DOM,使用JS修改元素得样式、类名、事件处理程序等来改变页面的外观和行为

3. DOM提供了事件模型,允许在页面中注册事件监听器,并对用户的交互做出响应


1.3 DOM的形成

DOM的形成过程主要涉及到浏览器对HTML文档的解析和构建,

1. 加载HTML文档,用户输入URL向服务器请求资源,获取到HTML文档

2. 解析HTML文档,浏览器按照一定语法、规则解析HTML文档。并将其转换为一个树结构的对象,即DOM树

3. 构建DOM树,解析HTML文档的过程中,浏览器会根据文档中的元素、属性和文本等内容构建DOM树。DOM树的每个节点都代表文档中的一个元素、属性或文本等内容

4. 提供访问接口,一旦DOM树构建完成,浏览器就会提供一系列的方法和属性来访问和操作DOM树中的节点和对象

提问:为什么需要将HTML转成DOM树来提供操作网页的接口?

因为HTML文档是字符串类型的,而DOM树是可遍历的树结构对象,相比于处理超长的字符串,对象更为容易处理。

 参考:浏览器渲染基本原理-CSDN博客


1.4 DOM的节点类型

DOM中总共有12种节点类型,它们都继承自一种基本类型。其中,最常用的节点类型有

1. Document节点,代表整个文档,是DOM树的根节点

2. Element节点,代表HTML文档中的标签元素,如<div>、<span>等

3. Text节点,代表元素中的文本内容

4. Comment节点,代表HTML文档中的注释内容


1.5 JS获取DOM节点

DOM是供JS操作网页元素的API,通过其提供的方法可以访问到网页元素对应的DOM树节点,

1. ID获取,这是获取单个元素节点(Element)的最快方式,因为ID在HTML文档中应该是唯一的

let element = document.getElementById('box')

2. 类名获取,这会返回一个元素节点集合,即HTMLCollection。即使只有一个元素匹配。

let elements = document.getElementsByClassName("myClassName")
// 可以通过索引访问,如elements[0]
// 也可以通过ID或name访问,如element['box'],box即元素ID
// 但第二种方法,不是所有浏览器都支持

3. 标签名获取,会返回一个元素节点集合

let elements = document.getElementsByTagName("div")

4. name属性获取,会返回一个元素节点集合。并不常用

let element = document.getElementsByName('name')

5. css选择器获取,

①document.querySelector(),返回匹配选择器的第一个节点

let element = document.querySelector('.className')

②document.querySelectorAll(),返回所有匹配选择器的节点集合NodeList

let element = document.querySelectorAll('.className')

注意:NodeList和HTMLCollection是存在一定区别的,

区别NodeListHTMLCollection
节点类型

可包含几乎所有类型的节点。

如,元素节点(Element)、文本节点(Text)、注释节点(Comment)等

只能包含元素节点(Element)
实时性

可以是动态的,也可以是静态的。

如,childNodes属性返回的NodeList是动态的;

而querySelectorAll方法返回的通常是静态的;

通常也是动态的,当文档中的元素发生变化时,HTMLCollection会自动更新以反映文档的变化。
访问方式通过索引来访问集合中的节点,如elements[index]

可通过索引访问节点;

还可通过元素的name或id属性值来快速访问元素节点,注意:不是所有浏览器都支持

6. 事件目标获取,在事件处理函数中,可以通过事件对象(event)的target属性来获取触发事件的元素节点。

document.querySelector('.className').addEventListener('click', function (event) {let clickedElement = event.target})

7. 除了上述这些方法,DOM API还提供了document.forms和document.images等诸多方法属性来获取DOM节点。感兴趣着,建议查阅相关官方文档


1.6 JS操作DOM节点

访问到DOM节点后,我们可以使用DOM API提供的一些属性和方法来修改节点属性,以达到动态的修改网页的内容和结构的效果。下面是常用的DOM节点操作方式:

1.61  修改节点属性

1. 修改HTML内容

let element = document.querySelector('#box')
element.innerHTML = '<p>New content</p>'

2. 修改文本内容

let element = document.querySelector('#box')
element.textContent = 'New text content'

3. 修改属性值,如直接修改并覆盖该元素节点的 所有 class 属性值

let element = document.querySelector('#box')
element.setAttribute('class', 'newClassName')

1.62 样式操作

1. 修改CSS样式

let element = document.querySelector('#box')
element.style.color = 'red'
element.style.fontSize = '20px'

2. 添加/移除类

let element = document.querySelector('#box')
element.classList.add('newClassName')
element.classList.remove('newClassName')

3. 切换类

let element = document.querySelector('#box')
element.classList.toggle('className');

1.63 节点的增删

1. 创建新节点

//创建新节点
let newElement = document.createElement('div')
newElement.textContent = 'New text content'

2. 插入新节点

let element = document.querySelector('#box')//作为子节点插入
element.appendChild(newElement)
//作为兄弟节点插入,
//element.parentNode 是element节点的父节点
//insertBefore 将newElement插入到 element.nextSibling之前
//element.nextSibling 是element节点的下一个相邻节点,如果没有那就是null
element.parentNode.insertBefore(newElement, element.nextSibling)
// 所有如果element 没有下一个相邻节点,newElement会被插到parentNode的末尾

3. 删除节点

let element = document.querySelector('#box')
// 访问父节点使用removeChild删除子节点
element.parentNode.removeChild(element)

1.64 事件处理

1. 添加事件监听器

let element = document.querySelector('#box')
element.addEventListener('click', function () {alert('Element clicked!')
})

2. 移除事件监听器

let element = document.querySelector('#box')
function handleClick() {alert('Element clicked!')
}
element.addEventListener('click', handleClick)
element.removeEventListener('click', handleClick)

1.65 综合案例

 以下是一个综合示例,展示了如何动态创建一个列表,并添加点击事件来处理列表项的点击:

<div id="container"></div>
<script>// 获取容器 元素节点let container = document.getElementById('container')// 创建列表项for (let i = 1; i <= 5; i++) {let listItem = document.createElement('div')listItem.textContent = 'Item ' + ilistItem.className = 'list-item'// 添加点击事件监听器listItem.addEventListener('click', function () {alert('You clicked on: ' + this.textContent)})// 将列表项作为容器子元素添加container.appendChild(listItem)}
</script>

2. 事件

2.1 基本概念

早期的互联网受限于网络带宽和服务器处理能力,网页的响应速度往往非常慢。为了提高用户体验,开发人员尝试将原本需要在服务器端处理的任务部分前移到客户端,让客户端通过JS来实现,以减少对服务器的依赖。如表单信息的格式验证等。

随着这种客户端处理策略的发展,浏览器开始支持越来越多的事件类型。

事件就是用户和网页交互时,由浏览器或渲染引擎根据用户的操作(如点击、输入、移动鼠标等)或某些系统事件(如网页加载、调整窗口的等)触发的行为。

这些行为通常与函数结合使用,当触发这些行为时,浏览器就会执行这些 “事件处理函数” 来响应事件,由此我们可以概括出:事件就是一种 “ 触发——响应 ”的机制。

同时,一个完整的事件机制必须满足三个要素(举例说明):

<button id="btu">btu</button>
let btu = window.document.querySelector('#btu')
btu.addEventListener('click', function () {console.log('触发事件处理函数')// ..........
})
  1. 事件源(EventTarget),也就是触发对象,比如上面的button
  2. 事件类型(type),比如上面的单击事件click
  3. 事件处理程序,比如上面的function

事件和DOM的关系:

  1. 由用户触发的事件,通常是注册在DOM节点上的,所以本质上,这类事件就是由DOM产生的资源。 
  2. 而由系统触发的事件,如resize这种窗口大小改变时触发的事件,通常是注册在window对象上的。注意:DOM节点被包含在document内,而,document被包含在window对象内。

2.2 事件绑定

1. 在HTML/XML标签中直接绑定。通常用于简单的场景,如onclick、onchange等,并直接指定处理函数名称

<button onclick="alert('你单击了一次')">按钮</button>

2. 在JS代码中给DOM绑定,通过JS访问DOM节点,并为其设置事件处理函数。优点是与HTML标签的分离,使文档结构更加清晰,便于管理和开发。

function handleClick() {alert('单击了一下')
}
document.getElementById('myButton').onclick = handleClick

3. 使用事件监听函数注册事件。它提供了更灵活的事件处理机制,能够为多个对象注册相同的事件处理函数,也可以为同一个对象注册多个事件处理函数,还可以在捕获阶段或冒泡阶段(详情见下方事件流)处理事件,并且可以绑定多个事件处理函数。

// 语法:
element.addEventListener(String type, Function listener, boolean useCapture)
type:事件类型
listener:事件处理函数
useCapture:true,指定的listener在捕获阶段触发;false,指定listener在冒泡阶段触发
-----------------------------------------------------------------------
document.getElementById('myButton').addEventListener('click',function () {alert('单击了一下')},false
)

4. 事件解绑

即移除绑定的事件处理函数,防止事件被重复触发或造成内存泄漏等问题。事件解绑通常与事件绑定相对应,如通过addEventListener注册的事件可以用removeEventListener来移除对应的侦听器

let btu1 = document.getElementById('btu1')
//单击一次,触发处理函数后解绑该处理函数,注意:处理函数不能匿名
btu1.addEventListener('click', function ok() {alert('单击了一下')this.removeEventListener('click', ok, false)
})//当临时注册一个事件时,可以在处理完毕之后迅速删除它,这样能够节省系统资源

注意:事件的处理函数最好不要使用箭头函数 ,否则处理函数内this不会指向源对象


2.3 事件流

1. 基本概念

事件流就是多个节点对象同一事件进行相应的先后顺序,一般有冒泡和捕获两种模式。通常指由于嵌套元素节点注册了相同的事件,并由子元素触发时,引起其上级元素触发相同事件

<div id="box"><button id="btu">btu</button>
</div>
<script>let btu = document.querySelector('#btu')let box = document.querySelector('#box')function check(e) {// e.target就是触发该处理函数的节点console.log('trigger by', e.target, 'and element is', this)}btu.addEventListener('click', check)box.addEventListener('click', check)
</script>

当我们点击button时,控制台输出:

会发现,由button触发的事件冒泡到了它的上级元素节点上 


2. 事件冒泡

事件流的默认模式,在DOM结构中,当一个元素被触发事件时,该事件会沿着DOM树向上传播,直到根节点或遇到某个节点阻止了事件的传播。这种传播方式称为事件冒泡。如 "1.基本概念" 中所展示的情况。


2. 事件捕获

与事件冒泡相反,事件捕获是事件从根节点向目标元素传播的过程。在事件捕获阶段,事件会先触发祖先元素的事件处理程序,然后再触发目标元素的事件处理程序。如下:

我们将  "1.基本概念" 中的box注册的单击事件,由默认的冒泡模式,改为捕获模式

box.addEventListener('click', check, true)

此时,再点击button,控制台会输出

会发现,由button触发的单击事件,却是button的上级元素box先一步调用单击事件处理函数。

如果不好理解,那么接着往下看


3. 事件处理顺序

事件由某一DOM节点触发,经历下面三个阶段

① 捕获阶段:事件从文档的根节点document向目标节点传播,如果绑定了捕获阶段的事件处理函数,则在这个阶段执行。

② 目标阶段:事件到达目标节点,如果为目标节点绑定了事件处理函数,则在这个阶段执行。

③ 冒泡阶段:事件从目标节点向文档的根节点传播,如果绑定了冒泡阶段的事件处理函数,则在这个阶段执行。

所以,"1.基本概念" 中的事件顺序应该是,

1)btu节点触发了单击事件click,浏览器从根节点document开始向btu节点遍历DOM树,发现了btu的上级元素box节点 也注册了单击事件,但默认了在冒泡阶段触发,所以不执行处理函数check

2)浏览器找到btu节点,开始触发处理函数

3)浏览器从btu节点开始向根节点document遍历,并执行box节点 注册的冒泡阶段单击事件(即执行check函数)


4. 事件混合

一句话概括,多重嵌套元素节点注册相同事件并分别指定了在冒泡阶段或捕获阶段执行


2.4 事件委托

事件委托是一种利用事件冒泡原理的技术,它通过将事件监听器绑定到父元素或祖先元素上,而不是直接绑定到目标元素上,来实现对多个子元素的事件处理。这种方式可以减少事件监听器的数量,提高性能,并简化代码结构。


2.5 阻止事件传播

即阻止事件冒泡/或捕获阶段的事件传播。某些场景我们不希望子元素节点触发的事件会传播到上级元素节点,这可以通过以下几种方式实现:

1. stopPropagation()方法,阻止捕获和冒泡阶段中当前事件的进一步传播(即传播到父元素)。这个方法只会阻止事件的冒泡阶段,不会阻止捕获阶段(除非在捕获阶段调用)

<div id="box"><button id="btu">btu</button>
</div>
<script>let btu = document.querySelector('#btu')let box = document.querySelector('#box')function check() {event.stopPropagation()console.log('trigger by', event.target, 'and element is', this)}btu.addEventListener('click', check)//捕获阶段调用box.addEventListener('click', check, true)// 冒泡阶段调用box.addEventListener('click', function () {console.log(this)})
</script>

点击点击button只会触发btu的处理函数,控制台输出:

box注册在冒泡阶段触发的处理函数,被btu注册的处理函数阻止事件传播到上级元

box注册在捕获阶段触发的处理函数,被box自己注册的处理函数阻止事件传播到这里

注意:stopPropagation()方法不能防止任何默认行为的发生;例如,对链接的点击仍会被处理。


2.  preventDefault()方法,阻止事件的默认行为。但此事件还是继续传播。它通常用于阻止表单提交submit的默认行为

<form id="myForm"><label for="username">Username:</label><input type="text" id="username" name="username" required /><button type="submit">Submit</button>
</form>let form = document.getElementById('myForm')
form.addEventListener('submit', function (event) {// 阻止表单的默认提交行为event.preventDefault()// ......在这里执行自定义逻辑,比如验证表单字段
})

因为JS表单的submit提交事件,默认会直接向服务器直接提交数据,但通常我们需要在提交之前对表单数据进行简单的格式验证,当格式正确后再发送到服务器。


3. event.stopImmediatePropagation(),不仅阻止事件的进一步传播,还阻止监听同一事件的其他事件监听器被调用

<button id="btu"></button>
<script>const btu = document.querySelector('#btu')btu.addEventListener('click', function () {console.log('button注册的第一个监听函数')})btu.addEventListener('click', function () {console.log('button注册的第二个监听函数')// // 阻止事件冒泡,并且阻止btu上绑定的其他 click 事件的事件监听函数的执行。event.stopImmediatePropagation()})btu.addEventListener('click', function () {console.log('button注册的第三个监听函数')// 该监听函数在stopImmediatePropagation后,故不会被执行})document.addEventListener('click', function () {console.log('给根节点注册的click监听函数')//btu 的 click 事件没有向上冒泡,该函数不会被执行})
</script>

注意:stopImmediatePropagation的阻止事件进一步传播是按照事件处理顺序来阻止的。

如果将给根节点注册的click事件处理函数设置为在捕获阶段执行,那么单击button,依旧会执行该处理函数。

document.addEventListener('click',function () {console.log('给根节点注册的click监听函数')//该函数会顺利执行,应为事件处理顺序在stopImmediatePropagation之前//....//如果在捕获阶段使用stopImmediatePropagation阻止事件传播//那么后续btu上注册的都不会执行},true)

2.6 事件类型

常见的事件类型包括:

事件类型事件名称触发时机作用举例
鼠标事件click用户单击元素触发常用于按钮点击、链接跳转等场景
dblclick双击元素时触发常用于打开文件、放大图片等操作
mouseover当鼠标指针移动到元素上方时触发常用于显示悬停效果、提示信息等
mouseout当鼠标指针移出元素时触发常用于处理元素移出时的清理操作等
mousemove当鼠标指针在元素上移动时持续触发常用于拖拽操作、鼠标轨迹跟踪等
mousedown当按下鼠标按钮时触发常用于处理按钮点击的开始阶段
mouseup当释放鼠标按钮时触发常用于处理按钮点击的结束阶段
键盘事件keydown按下键盘上的任意键时触发常用于实现键盘快捷键、搜索框自动完成等功能
keyup释放键盘上的任意键时触发常用于检测按键释放后的操作
表单事件submit当表单提交时触发常用于验证表单数据、阻止默认提交行为、异步提交等
change当表单元素的值发生变化时触发(如输入框、选择框的值改变)常用于实时搜索、过滤数据、更新页面内容等
focus当元素获得焦点时触发(如输入框被点击或Tab键选中)常用于改变输入框的样式、显示/隐藏帮助文本或提示信息等
blur当元素失去焦点时触发常用于处理元素失去焦点后的操作,如验证输入内容
窗口事件load当页面或资源(如图片、CSS文件等)完全加载完成时触发常用于初始化页面内容、加载数据等
unload当页面卸载时触发,通常用于清理资源或执行最后的操作常用于清理资源、保存状态等
resize当浏览器窗口大小改变时触发常用于响应式设计、调整页面布局等
scroll当页面滚动时触发常用于创建滚动效果、懒加载图片等

注意: 如果需要在事件监听器addEventListener以外的地方使用,如HTML中和JS赋值绑定中(2.2事件绑定中的1和2),需要使用on<event>的格式来声明事件


2.7 自定义事件

2.71 基本概念

JS内置的DOM事件通常是基于Event接口或其子类实现的。Event接口表示在EventTarget(如元素,文档,窗口等)上出现的事件。除了这些内置事件(如鼠标事件、键盘事件等),我们也可以通过事件接口(或者说构造函数)来自定事件。


2.72 Event

1.  Event构造函数,用于创建一个新的事件对象 Event。如,

let event = new Event(type, options)type ,事件类型,如 "click" 这样的的字符串
options(可选) ,接受以下字段bubbles(可选),默认值为 false,表示该事件是否冒泡。cancelable(可选),默认值为 false,表示该事件能否被取消,即是否可以调用 preventDefault() 来阻止默认行为(注意:别与移除事件监听器混淆)composed(可选),默认值为 false,指示事件是否会在影子 DOM 根节点之外触发侦听器,本篇不作详细介绍

使用举例,创建一个支持冒泡且不能被取消的 look 事件。

//创建新的事件
const ev = new Event('look', { bubbles: true, cancelable: false })
// 监听自定义事件
btu.addEventListener('look', function () {console.log('btu触发look')
})
document.addEventListener('look', function () {console.log('look冒泡到document')
})
btu.addEventListener('click', function () {btu.dispatchEvent(ev)//自定义的事件使用dispatchEvent来触发
})
//点击button,顺序输出:btu触发look     look冒泡到document

2. ​Event构造函数作为JS内置对象的一种,提供了许多事件相关的属性和方法。而事件对象就利用这是实例属性和方法来储存或操作事件相关的信息(包括本次触发事件的事件类型、事件目标、触发元素等)。

我们查看1中定义的初始ev对象,以及btu触发look事件后的ev对象

console.dir(ev)
btu.addEventListener('look', function () {console.dir(ev)console.log(ev === event)//true,同一引用
})

控制台: 


2.72 event的常用属性/方法

1. 常用属性

属性介绍
type事件类型,
bubblesEvent实例只读属性,表示当前事件是否会进行冒泡。只能在event创建时设置
cancelableEvent实例只读属性,表示当前事件是否能取消。只能在event创建时设置
isTrusted只读属性(无法修改),自定义事件或被重定义的事件为false,内置事件为true
target事件最初发生的元素,用以确定用户与哪个元素进行了交互
currentTarget当前事件监听器所绑定的元素,即使事件是从子元素触发的,currentTarget始终指向绑定事件处理函数的元素
clientX 和 clientY获取鼠标相对于浏览器窗口左上角的坐标。常用于确定鼠标在窗口中的位置
key 在键盘事件中,key属性返回按下的具体字符
button在鼠标事件中,表示按下了哪个鼠标按钮。0(左键)、1(滚轮)、2(右键)
key 在键盘事件中,key属性返回按下的具体字符
defaultPrevented只读属性,示当前事件是否调用了preventDefault()方法,从而阻止了浏览器的默认行为。

2. 常用方法

方法介绍
preventDefault()阻止事件的默认行为。例如,点击链接时,浏览器会跳转到链接地址,使用preventDefault()可以阻止这一行为
stopPropagation()阻止事件冒泡,即阻止事件从子元素向父元素传递
stopImmediatePropagation()除了阻止事件冒泡外,还会阻止当前元素上其他同类型事件处理程序的执行

2.73 特殊的自定义事件

观察“2.72 event的常用属性/方法” 和 “2.72 Event 中对ev对象的检查 ”,会发现,某些属性在ev上并不存在。这是为什么呢?

在 “2.71基本概念” 中提到 JS内置的DOM事件通常是基于Event接口或其子类实现的。Event是基层事件接口,而它的子类接口继承了Event的部分属性,同时新增了自己持有的某属性或方法。

如键盘事件,如果我们要自定义一个键盘事件KeyboardEvent构造函数:

<input type="text" id="myInput" placeholder="在这里输入..." />
<p id="output"></p>
<script>
//DOMContentLoaded事件,文档被加载和解析,并且 DOM 被完全构造时触发
//但链接的资源(例如图像、样式表和子框架)可能尚未被加载document.addEventListener('DOMContentLoaded', (event) => {const input = document.getElementById('myInput')const output = document.getElementById('output')// 监听输入框的键盘事件input.addEventListener('keydown', (event) => {output.textContent = `你按下了键: ${event.key}`})// 创建一个自定义的键盘事件function triggerCustomKeyEvent(key) {const event = new KeyboardEvent('keydown', {key: key, // 按键的值(例如 'a', 'Enter' 等)code: key, // 物理按键的代码bubbles: true, // 冒泡cancelable: true // 是否可以调用 preventDefault() 来阻止默认行为})// 触发自定义事件input.dispatchEvent(event)}// 在页面加载后的2秒钟触发一个自定义的 'a' 键按下事件setTimeout(() => {triggerCustomKeyEvent('a') // 'a'}, 2000)})
</script>

所以,如果你想定义一些特别的自定义事件,键盘事件,鼠标事件等,就需要使用KeyboardEvent,MouseEvent 等Event的子类构造函数来实现。

对Event的子类有过一点了解后,我们对2.72Event自定义事件进行补充:

对于我们自己的全新事件类型,更加推荐使用Event的子类CustomEvent,它与Event技术上基本一样,但在第二个参数(options)中,我们可以为添加一个初始化事件时传递的任何信息:

<h1 id="elem">Hello for John!</h1>
<script>// 事件附带给处理程序的其他详细信息elem.addEventListener('hello', function (event) {alert(event.detail.name)})elem.dispatchEvent(new CustomEvent('hello', {detail: { name: 'John' }}))
</script>

请注意,随着JavaScript标准的不断发展,新的事件属性和方法可能会被引入,而一些旧的或不再常用的可能会被废弃或移除。因此,对自定义事件相关感兴趣者,建议查阅最新的ECMAScript规范或JavaScript文档以获取最准确的信息。 

 若有错误或描述不当的地方,烦请评论或私信指正,万分感谢 😃

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

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

相关文章

缓存常见问题:缓存穿透、雪崩、击穿及解决方案分析

1. 什么是缓存穿透&#xff0c;怎么解决&#xff1f; 缓存穿透是指用户请求的数据在缓存中不存在即没有命中&#xff0c;同时在数据库中也不存在&#xff0c;导致用户每次请求该数据都要去数据库中查询一遍。如果有恶意攻击者不断请求系统中不存在的数据&#xff0c;会导致短时…

Java面试场景题(1)---如何使用redis记录上亿用户连续登陆天数

感谢uu们的观看&#xff0c;话不多说开始~ 对于这个问题&#xff0c;我们需要先来了解一下~ 海量数据都可以用bitmap来存储&#xff0c;因为占得内存小&#xff0c;速度也很快 我大概计算了一下~ 完全够&#xff1a;String类型512M 1byte 8个bit位 8个状态 512M1024byt…

计算机组成原理(笔记7高速缓冲存储器Cache,计算机组成原理的重难点全、直接、组相连)

为什么要设立高速缓冲存储器 &#xff08;Cache&#xff09;&#xff1f; Cache是介于CPU和主存之间的小容量存储器&#xff0c;存取速度比主存快。它能高速地向CPU提供指令和数据&#xff0c;加快程序的执行速度。它是为了解决CPU和主存之间速度不匹配而采用的一项重要技术。…

01 一篇读懂25机械考研复试超全流程讲解|考研面试经验和面试真题快来背诵!

复试面试流程及经验汇总篇 千万不要小瞧出成绩前的准备以及最常见面试问题你提前熟记于心&#xff0c;面试再遇到&#xff0c;能够有逻辑有条理的回答出不是空洞的话&#xff0c;给导师的印象分就肯定高。 考研复试面试最全最完整的实用攻略&#xff0c;从出考研初试成绩前到…

《深度学习》模型的部署、web框架 服务端及客户端案例

目录 一、模型的部署 1、模型部署的定义与目的 1&#xff09;定义 2&#xff09;目的 2、模型部署的步骤 1&#xff09;导出模型 2&#xff09; 部署模型 3&#xff09;测试模型 4&#xff09;监控模型 3、模型部署的方式 1&#xff09;云端部署 2&#xff09;嵌入…

RHCE--at,crontab例行性工作

一&#xff1a;安装at &#xff08;1&#xff09;配置yum仓库&#xff1a;以配置网络源举例&#xff1a; 先在/etc/yum.repos.d/ 目录下创建一个以.repo结尾的文件 vim /etc/yum.repos.d/aliyun.repo 写入可以在阿里云镜像站查找appstream和baseos的地址阿里巴巴开源镜像站…

内核调度hh

的国际化的比较好 11 其他

英语语法学习框架(考研)

一、简单句 英语都是由简单句构成&#xff0c;简单句共有五种基本句型&#xff1a;①主谓&#xff1b;②主谓宾&#xff1b;③主谓宾宾补&#xff1b;④主谓宾间宾&#xff08;间接宾语&#xff09;&#xff1b;⑤主系表&#xff1b; 其中谓语是句子最重要的部分&#xff0c;谓…

别再用老旧架构了!单元化构建超强弹性和容错系统!

0 关键收获 单元化架构提高了微服务的弹性和容错性。可观察性对于开发和运营单元化架构至关重要。单元路由器是单元基础架构的关键组件&#xff0c;它需要快速响应单元可用性和健康变化。要成功采用单元化架构&#xff0c;需要全面和综合的方法来实现可观察性。单元化架构利用…

改变函数调用上下文:apply与call方法详解及实例

目录 改变函数调用上下文&#xff1a;apply与call方法详解及实例 一、什么是 apply 方法&#xff1f; 1、apply 语法 2、apply 示例 二、什么是 call 方法&#xff1f; 1、call 语法 2、call 示例 三、apply 和 call 的共同与差异 1、apply 和 call 的共同点 2、apply…

centos7-网络模式选择NAT连接时遇到的问题

今天花了我一上午的时间&#xff0c;必须要记录一下。 新创建的虚拟机&#xff0c;选择的centos7-NAT的网路连接模式。 科普一下: 我选择的NAT模式&#xff0c; 然后改了 vi /etc/sysconfig/network-scripts/ifcfg-ens33文件的 source ~/.bashrc和reboot之后 执行service n…

nginx 快速入门

配置文件 nginx.conf 每个 http 块可以包括多个 server 块&#xff0c;而每个 server 块就相当于一个虚拟主机 #这一行表示这个server块监听的端口是80&#xff0c;只要有请求访问了80端口&#xff0c;此server块就处理请求listen 80;# 表示这个server块代表的虚拟主机的名字…

优雅的入参校验,Valid常用校验

更好的阅读体验&#xff1a;优雅的入参校验&#xff0c;Valid常用校验 对于前端传递的参数&#xff0c;正常情况下后端是要进行一些必要的校验&#xff0c;最简单的做法是用 if 效果是可以&#xff0c;但不优雅。使用 Validator 代替 if&#xff0c;就会优雅很多 ps&#xff…

重学SpringBoot3-Spring Data JPA简介

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-Spring Data JPA简介 1. 什么是 Spring Data JPA&#xff1f;2. Spring Data JPA 的核心概念2.1. 实体&#xff08;Entity&#xff09;2.2. Repository&…

SpringBoot整合mybatisPlus实现批量插入并获取ID

背景&#xff1a;需要实现批量插入并且得到插入后的ID。 使用for循环进行insert这里就不说了&#xff0c;在海量数据下其性能是最慢的。数据量小的情况下&#xff0c;没什么区别。 【1】saveBatch(一万条数据总耗时&#xff1a;2478ms) mybatisplus扩展包提供的&#xff1a;…

吴恩达深度学习(9)

经典的神经网络&#xff1a; 残差网络&#xff08;ResNet&#xff09; 太深的神经网络容易出现梯度消失与梯度爆炸等问题。 跳跃连接&#xff0c;能从一层中得到激活并将其传递给下一层&#xff0c;甚至更深的网络层。利用这个可以训练网络层很深很深的残差网络&#xff08;R…

Go 1.19.4 命令调用、日志、包管理、反射-Day 17

1. 系统命令调用 所谓的命令调用&#xff0c;就是通过os&#xff0c;找到系统中编译好的可执行文件&#xff0c;然后加载到内存中&#xff0c;变成进程。 1.1 exec.LookPath&#xff08;寻找命令&#xff09; 作用&#xff1a; exec.LookPath 函数用于在系统的环境变量中搜索可…

海思hi3536c配置内核支持USB摄像头

linux内核版本&#xff1a;linux-3.18.20 配置步骤 进入Device Drivers 选择Multimedia support&#xff0c;并进入 选择Media USB Adapters&#xff0c;并进入 如下图&#xff0c;选择这几项&#xff1a; 保存退出&#xff0c;重新编译内核下载 内核更新后&#xff0c…

DIFFEDIT: DIFFUSION-BASED SEMANTIC IMAGE EDIT- ING WITH MASK GUIDANCE

https://arxiv.org/pdf/2210.11427 问题引入 针对的问题是输入text prompt完成对图片的编辑&#xff0c;基于的是T2I model&#xff1b;本文的方法不需要额外提供mask来将任务变为inpaint任务&#xff0c;而是可以自动的根据text prompt来提取出需要编辑区域的mask methods

支付域——支付背景

摘要 支付体系作为现代金融的重要组成部分,承担着资金流转与经济交易的关键职能。随着科技的发展,全球支付方式迅速演变,尤其是在中国,移动支付、互联网支付等新兴方式已广泛应用。传统的现金、银行卡支付逐渐被数字支付所取代,支付宝、微信支付等第三方支付机构成为主流…