当前位置: 首页 > news >正文

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文档以获取最准确的信息。 

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

相关文章:

JS事件和DOM

1. DOM 1.1 基本概念 DOM&#xff0c;全称 Document Object Model&#xff0c;即文档对象模型。它是 Web 上最常用的 API 之一&#xff0c;是加载在浏览器中的文档模型&#xff0c;可以将文档表示为节点树&#xff08;或称 DOM 树&#xff09;&#xff0c;其中每个节点代表文…...

CAS 详解

目录 Java 中 CAS 是如何实现的? CAS 算法存在哪些问题? ABA 问题 循环时间长开销大 只能保证一个共享变量的原子操作 Java 中 CAS 是如何实现的? 在 Java 中&#xff0c;实现 CAS&#xff08;Compare-And-Swap, 比较并交换&#xff09;操作的一个关键类是Unsafe。 Un…...

AI大模型那么火,教你一键Modelarts玩转开源LlaMA(羊驼)大模型

近日&#xff0c; LlaMA(羊驼) 这个大模型再次冲上热搜&#xff01; LLaMA&#xff08;Large Language Model Meta AI&#xff09;&#xff0c;由 Meta AI 发布的一个开放且高效的大型基础语言模型&#xff0c;共有 7B、13B、33B、65B&#xff08;650 亿&#xff09;四种版本。…...

Spring AI Alibaba: 支持国产大模型的Spring ai框架

Spring AI &#xff1a;java做ai应用的最好选择 过去&#xff0c;Java在AI应用开发方面缺乏一个高效且易于集成的框架&#xff0c;这限制了开发者快速构建和部署智能应用程序的能力。 Spring AI正是为解决这一问题而生&#xff0c;它提供了一套统一的接口&#xff0c;使得AI功…...

ChatGPT4o、o1 谁才是最佳大模型?

如何选择合适的 ChatGPT 模型&#xff1f;OpenAI 更新细节与 GPTs 的深入解析 随着人工智能的发展&#xff0c;ChatGPT 已成为众多用户的强大助手&#xff0c;广泛应用于写作、编程、学习和商业等多个领域。然而&#xff0c;面对 OpenAI 提供的众多模型&#xff08;如 GPT-4、…...

[笔记] 关于CreateProcessWithLogonW函数创建进程

函数介绍 https://learn.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw BOOL CreateProcessWithLogonW([in] LPCWSTR lpUsername,[in, optional] LPCWSTR lpDomain,[in] …...

Ubuntu的Qt编译环境配置

1、找不到C和C编译器 利用run文件安装QT6.8.0和QT5.12.2版本后&#xff0c;打开QtCreator时&#xff0c;找不到编译器。 可在终端中查找gcc和g版本&#xff0c;如果没有就安装。 gcc --version g --version 如果没有就安装&#xff1a; sudo apt-get install gcc sudo apt-…...

12 django管理系统 - 注册与登录 - 登录

为了演示方便&#xff0c;我就直接使用models里的Admin来演示&#xff0c;不再创建用户模型了。 ok&#xff0c;先做基础配置 首先是在base.html中&#xff0c;新增登录和注册的入口 <ul class"nav navbar-nav navbar-right"><li><a href"/ac…...

2020年计算机网络408真题解析

第一题&#xff1a; 解析&#xff1a;OSI参考模型网络协议的三要素 网络协议的三要素&#xff1a;语法 &#xff0c;语义&#xff0c;同步&#xff08;时序&#xff09; 语法&#xff1a;定义收发双方所交换信息的格式 语法&#xff1a;定义收发双方所要完成的操作 网页的加载 …...

速盾:cdn高防服务器防火墙的特性是什么?

CDN高防服务器防火墙是一种专门为互联网应用提供安全防护的网络安全设备。它采用先进的技术和算法&#xff0c;通过对网络流量进行过滤和检测&#xff0c;以防止恶意攻击和非法访问&#xff0c;保障网络服务的可用性和安全性。CDN高防服务器防火墙的特性主要包括以下几个方面&a…...

小程序分包和预加载

一、目的 分包的目的&#xff1a; 提升小程序的首屏加载速度&#xff0c;其原理和PC端网页的路由懒加载非常类似。即当我们第一个打开一个小程序的时候&#xff0c;只加载主包以及一些公共的资源&#xff0c;当调到某个页面的时候&#xff0c;在加载该页面所在的分包&#xf…...

【MATLAB 串口调试+虚拟串口测试】

文章目录 前言一、matlab 串口二、测试串口1.从系统中获取串口号2.避免串口打开被占用3. 安装虚拟串口4. 打开串口助手和MATALB 进行测试 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 项目需要&#xff1a; 提示&#xff1a;以下是本篇文章正文…...

mac 安装最新版nginx

1. clone最新版本源代码&#xff1a; git clone https://github.com/nginx/nginx.git 2. 下载PCRE 没有PCRE那我们就下&#xff0c;下载地址&#xff1a;https://sourceforge.net/projects/pcre/files/pcre/&#xff0c;笔者下载的pcre-8.45.zip&#xff0c;下载之后解压到ngi…...

极氪汽车困局:营销频繁车、产品力不足

“ 极氪汽车的“车上吃火锅”营销活动虽登上热搜&#xff0c;但因频繁忽视老用户和产品力不足的争议&#xff0c;并未赢得消费者好感&#xff0c;反而加剧负面印象。 ” 科技新知 原创 作者丨颜瞾 编辑丨蕨影 近日&#xff0c;背靠吉利集团的极氪…...

Icecream 与 Python 日志库及性能分析整合指南

简介 Icecream 是一个用于简化 Python 调试过程的库&#xff0c;它允许开发者轻松打印变量名和它们的值。Python 的 logging 库则提供了一个强大的日志记录系统&#xff0c;用于跟踪应用程序的运行情况。而性能分析则是评估代码执行效率的重要手段。本指南将介绍如何将 Icecre…...

请解读下面的程序:pat =re.compile(r‘\d+‘)res = pat.search(‘www.ddd996.com‘)res.group()

请解读下面的程序&#xff1a; pat re.compile(r\d) res pat.search(www.ddd996.com) res.group() 这段程序使用了正则表达式模块re来搜索字符串中的数字。首先&#xff0c;通过re.compile函数创建了一个正则表达式对象pat&#xff0c;该正则表达式是r\d&#xff0c;意味着匹…...

Fibonacci任意一位的值得算法

csDP写法 using System; class Program {static void Main(string[] args){Console.WriteLine("请输入一个非负整数&#xff1a;");// 读取用户输入while(true){string input Console.ReadLine();int n Convert.ToInt32(input);if (n < 0){Console.WriteLine(&…...

gbn,sr和tcp的区别

这是关于三种不同协议&#xff08;GBN、SR、TCP&#xff09;处理传输时序和丢包的行为比较。我们可以分别填充并解释它们的处理机制&#xff1a; GBN&#xff08;Go-Back-N&#xff09;协议&#xff1a; 类型发送方的计时器保存的是啥接收方收到失序的分组怎么办超时的时候发…...

FastGPT本地开发 之 通过Navicat管理MongoDB、PostgreSQL数据库

1. 背景 前期已经完成FastGPT的本地化部署工作&#xff0c;通过Docker启动FastGPT的相关容器即可运行。&#xff08;共6个容器&#xff09; 2.本地化开发 2.1 前置依赖 2.2 源码拉取 git clone gitgithub.com:labring/FastGPT.git2.3 数据库管理 本地化运行的FastGPT使用…...

hardhat部署智能合约

Hardhat安装 安装node 可以使用 nvm 安装node GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions 安装Hardhat 打开命令行工具&#xff0c;输入&#xff1a; mkdir hardhat-demo cd hardhat-demo npm i…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...