web的五个Observer API
IntersectionObserver:
一个元素从不可见到可见,从可见到不可见
??IntersectionObserver
是一种浏览器提供的 JavaScript API
,用于监测元素与视窗的交叉状态。它可以告诉开发者一个元素是否进入或离开视窗,以及两者的交叉区域的大小和位置。
它提供了一种高效的方法来观察元素是否进入或离开视窗,而无需依赖滚动事件或定时器。它可以通过回调函数及设定的阈值来实时地通知开发者目标元素与视窗的交叉状态,并根据需要采取相应的操作。
特性:
- 异步执行:
IntersectionObserver
是异步执行的,它使用浏览器的内部优化机制,不会阻塞主线程,从而避免了性能问题。 - 节省资源:相比于传统的滚动事件或定时器,
IntersectionObserver
可以精确地观察元素与视窗的交叉状态,避免了不必要的计算和回调触发,从而节省了资源的消耗。 - 多目标观察:
IntersectionObserver
可以同时观察多个目标元素,通过回调函数逐个通知开发者它们的交叉状态,方便进行批量操作。 - 自定义阈值:开发者可以设定一个或多个阈值,用来定义元素与视窗的交叉比例。当交叉比例超过或低于阈值时,会触发相应的回调函数。
API介绍:
- **IntersectionObserver(callback, options):**创建新的实例,传入回调函数和配置对象。
- **observe(target):**观察指定目标元素,传入目标元素。
- **unobserve(target):**停止观察指定目标元素。
- **disconnect():**停止观察,断开与所有目标元素的关联。
创建一个交叉观察器
通过调用 IntersectionObserver 构造函数,创建交叉观测器,并将回调函数传给它,当一个方向或另一个方向越过阈值时,就运行该函数:
let options = {root: document.querySelector("#scrollArea"),rootMargin: "0px",threshold: 1.0,
};let observer = new IntersectionObserver(callback, options);
阈值为 1.0 意味着目标元素完全出现在root
选项指定的元素中 100% 可见时,回调函数将会被执行。
IntersectionObserver 选项
传递到IntersectionObserver()构造函数的options
对象,可以控制在什么情况下调用观察器的回调。它有以下字段:
root
用作视口的元素,用于检查目标的可见性。必须是目标的祖先。如果未指定或为null
,则默认为浏览器视口。
rootMargin
根周围的边距。其值可以类似于 CSSmargin属性,例如"10px 20px 30px 40px"
(上、右、下、左)。这些值可以是百分比。在计算交叉点之前,这组值用于增大或缩小根元素边框的每一侧。默认值为全零。
threshold
一个数字或一个数字数组,表示目标可见度达到多少百分比时,观察器的回调就应该执行。如果只想在能见度超过 50% 时检测,可以使用 0.5 的值。如果希望每次能见度超过 25% 时都执行回调,则需要指定数组 [0, 0.25, 0.5, 0.75, 1]。默认值为 0(这意味着只要有一个像素可见,回调就会运行)。值为 1.0 意味着在每个像素都可见之前,阈值不会被认为已通过。
定位要观察的元素
创建一个观察器后,需要给定一个目标元素进行观察。
let target = document.querySelector("#listItem");
observer.observe(target);// 我们为观察器设置的回调将在第一次执行,
// 它将等待我们为观察器分配目标(即使目标当前不可见)
每当目标满足该IntersectionObserver
指定的阈值(threshold),回调被调用。回调接收IntersectionObserverEntry对象和观察器的列表:
let callback = (entries, observer) => {entries.forEach((entry) => {// 每个条目描述一个目标元素观测点的交叉变化:// entry.boundingClientRect// entry.intersectionRatio// entry.intersectionRect// entry.isIntersecting// entry.rootBounds// entry.target// entry.time});
};
其中,
entry
对象包括以下这些参数:**entry.boundingClientRect:**当前观察元素的矩形区域,top/right/bottom/left属性可以获得此时相对视区的距离,width/height属性包含尺寸。此属性和
Element.getBoundingClientRect()
这个API方法非常类似。**entry.intersectionRatio:**当前元素被交叉的比例。比例要想非常详细,需要
IntersectionObserver()
函数的第2个可选参数中设置thresholds
参数,也就是设置触发交叉事件的阈值。**entry.intersectionRect:**和视区交叉的矩形大小。
**entry.isIntersecting:**如果是true,则表示元素从视区外进入视区内。
**entry.rootBounds:**窗体根元素的矩形区域对象。
**entry.target:**当前交叉的元素。
entry.time:当前时间戳。
举个栗子
var zxxObserver = new IntersectionObserver(function (entries) {entries.forEach(function (entry) {if (entry.isIntersecting) {// entry.target元素进入区域了}});
});
// 观察元素1,2,...
zxxObserver.observe(ele1);
zxxObserver.observe(ele2);
...
用文字解释下就是这两步:
- 定义元素交叉后干嘛干嘛;
- 需要观察那些元素;
实际开发的时候,主要工作就是对entries.forEach
这部分的代码进行处理。
应用场景
探秘神奇的IntersectionObserver:释放网页性能的黑科技!IntersectionObserver 提供 - 掘金
图片懒加载
通过使用IntersectionObserver
,可以延迟加载图片,只在它们进入视窗时才开始加载。这样可以减少初始页面加载时间,并节省带宽和资源。
实现图片懒加载的步骤如下:
- 创建
IntersectionObserver
实例,并指定观察的目标元素。- 在回调函数中,判断目标元素是否进入视窗。
- 若目标元素进入视窗,将其真实的图片地址赋给元素的
src
属性,触发图片加载。+ 把所有需要延迟加载的图片用一个盒子包起来,设置宽高和默认占位图
+ 开始让所有IMG的SRC为空,把真实图片的地址放到IMG的自定义属性上,让IMG隐藏
+ 等到所有其他资源都加载完成后,再开始加载图片
+ 对于很多图片,需要当页面滚动的时候,当前图片区域显示出来后在加载真实图片
import { useEffect, useRef } from "react"
import styles from './LazyImg.module.scss'const Index = () => {const ImgRef = useRef<HTMLDivElement>(null)const handleLoad = (entries: IntersectionObserverEntry[]) => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.target as HTMLImageElement;img.src = img.getAttribute("data-src") || ""; // 将真实的图片地址赋给 src 属性intersectionObserver.unobserve(img); // 停止观察该图片}})}const intersectionObserver = new IntersectionObserver(handleLoad)useEffect(() => {if (ImgRef.current) {const imgs = ImgRef.current.querySelectorAll('img');imgs.forEach(img => {intersectionObserver.observe(img)})}return () => {intersectionObserver.disconnect()}}, [])return <><div className={styles.main_box} ref={ImgRef}><img src="" alt="" data-src="../assets/module182_style1.png" /><img src="" alt="" data-src="../assets/module182_style2.png" /><img src="" alt="" data-src="../assets/module182_style1.png" /></div></>
}export default Index
用户兴趣埋点
规则是当某元素在视口停留时间达到2秒以上时,被认为用户对该元素感兴趣。
步骤如下:
- 创建
IntersectionObserver
实例,并指定观察的目标元素。- 在回调函数中,根据目标元素的交叉状态判断用户对该元素的兴趣。
- 根据规则判断适口停留时间是否满足条件。
- 如果满足条件,则记录兴趣数据或触发相应操作。
import { useEffect, useRef } from "react"const Index = () => {const BuriedRef = useRef<HTMLDivElement>(null)const handleBuried = (entries: IntersectionObserverEntry[]) => {entries.forEach(entry => {if (entry.isIntersecting && entry.intersectionRatio >= 0.5 &&entry.intersectionRect.width >= entry.boundingClientRect.width * 0.5 &&entry.intersectionRect.height >= entry.boundingClientRect.height * 0.5 &&entry.time >= 2000) {// 埋点操作}})}const intersectionObserver = new IntersectionObserver(handleBuried)useEffect(() => {if (BuriedRef.current) {const boxs = BuriedRef.current.querySelectorAll('item');boxs.forEach(box => { intersectionObserver.observe(box) })}return () => {intersectionObserver.disconnect()}}, [])return <div ref={BuriedRef}><div className="item"><img src="" alt="" data-src="../assets/module182_style1.png" /></div><div className="item"><img src="" alt="" data-src="../assets/module182_style2.png" /></div><div className="item"><img src="" alt="" data-src="../assets/module182_style1.png" /></div></div>
}export default Index
进阶
- 优化阈值设置
设置合适的交叉比例阈值可以减少不必要的回调函数触发。过多的阈值设置可能会导致频繁的回调函数执行,因此需要根据具体情况进行优化。 - 避免频繁的回调函数执行
由于IntersectionObserver
可能在短时间内多次触发回调函数,为了避免频繁的操作或网络请求,可以使用节流(throttling
)或防抖(debouncing
)技术进行处理。节流可以限制回调函数的执行频率,而防抖可以在指定时间内的连续触发中只执行最后一次。 - 优化性能与资源消耗
尽管IntersectionObserver
可以提供更好的性能,但当处理大量元素或复杂布局时,仍需考虑性能和资源消耗。可以结合使用时间间隔、限制最大触发次数等策略,确保在合理的范围内处理交叉状态变化。 - 控制监听范围
仅监听真正需要监测的元素,避免不必要的监听。过多的监听会增加性能消耗,并可能导致不必要的回调函数触发。 - 谨慎使用多个
IntersectionObserver
当需要监测多个元素时,使用多个IntersectionObserver
可能会增加代码复杂性和性能开销。在这种情况下,可以考虑合并监听逻辑,减少IntersectionObserver
的数量。 - 处理边界情况
注意处理边界情况,如元素尺寸变化、容器滚动等。在这些情况下,IntersectionObserver
可能无法及时检测到交叉状态的变化,需要进行额外的处理。 - 考虑兼容性
尽管大多数现代浏览器都支持IntersectionObserver
,但在一些旧版本浏览器中可能不被支持。为了确保兼容性,可以使用IntersectionObserver
的polyfill
或提供降级方案。 - 处理
IntersectionObserver
回调中的异步操作- 取消异步操作:在某些情况下,当元素离开视窗或不再需要异步操作时,可能需要取消正在进行的异步操作。例如,当用户迅速滚动页面时,可能需要取消之前触发的异步操作,以避免不必要的网络请求或计算。可以使用适当的方法,如取消
Promise
或中断正在进行的异步任务。 - 性能优化:对于耗时的异步操作,需要注意性能优化。考虑使用并发执行、缓存结果或其他优化策略,以减少延迟和资源消耗。
- 取消异步操作:在某些情况下,当元素离开视窗或不再需要异步操作时,可能需要取消正在进行的异步操作。例如,当用户迅速滚动页面时,可能需要取消之前触发的异步操作,以避免不必要的网络请求或计算。可以使用适当的方法,如取消
- 清理资源
当不再需要IntersectionObserver
监听或元素被销毁时,确保正确地清理和释放相关的资源。取消监听、解除绑定和清理回调函数,以避免内存泄漏和不必要的资源占用。 - 兼容性:尽管现代浏览器大多支持
IntersectionObserver
,但在一些旧版本的浏览器中可能不被支持。为了确保广泛的兼容性,开发者需要根据项目需求考虑是否需要提供降级方案或使用polyfill
。 - 事件顺序不确定性:由于
IntersectionObserver
是异步执行的,不同元素的回调函数执行顺序是不确定的。这可能会导致在处理相关逻辑时需要额外的注意,以确保正确的顺序和逻辑关联性。
MutationObserver
监听元素的属性和子节点的变化
??MutationObserver
的目标是解决传统的DOM
变化监听方式的局限性和性能问题,并提供更高效、灵活的DOM
变化监视机制。 在过去,开发人员使用DOM
事件监听或定时器轮询的方式来监视DOM
的变化。
MutationObserver用于监听DOM对象的变更,包括节点属性的变化、子节点的增删改等。提供了方便的方式监听DOM变化。
API介绍:
- **
MutationObserver(callback)
:**创建新的实例,传入变动时的回调函数。 - **
observe(target, config)
:**开始观察指定目标节点,传入目标节点和配置对象。 - **
disconnect()
:**停止观察,断开与所有目标节点的关联。 - takeRecords():从 MutationObserver 的通知队列中删除所有待处理的通知,并将它们返回到MutationRecord对象的新Array中。
举个栗子
// 选择需要观察变动的节点
const targetNode = document.getElementById("some-id");// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };// 当观察到变动时执行的回调函数
const callback = function (mutationsList, observer) {// Use traditional 'for loops' for IE 11for (let mutation of mutationsList) {if (mutation.type === "childList") {console.log("A child node has been added or removed.");} else if (mutation.type === "attributes") {console.log("The " + mutation.attributeName + " attribute was modified.");}}
};// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);// 以上述配置开始观察目标节点
observer.observe(targetNode, config);// 之后,可停止观察
observer.disconnect();
??config
对象在MutationObserver
的observe
方法中用于指定哪些类型的 DOM 变动需要被观察。config
对象可以包含以下属性,每个属性都是一个布尔值,指示是否应该观察对应类型的变动:
attributes: 当被观察元素的属性变动时触发。注意,这个选项不会捕获
class
属性的变动,除非通过attributeNameFilter
明确指定。要捕获class
属性的变动,可以监视attributeFilter
为['class']
,或者使用子树变动(childList
)和特性变动(attributes
)的组合,因为类名的变化通常会导致子节点(如span
元素,用于通过 CSS 类应用样式)的添加或移除。childList: 当被观察元素的子节点变动时触发(添加或移除子节点)。
subtree: 当被观察元素的所有后代节点变动时触发。这个选项扩大了观察范围,使得变动不仅限于直接子节点,还包括所有更深层次的子节点。
characterData: 当被观察元素的文本内容变动时触发。这个选项仅对文本节点或设置了
nodeType
为Node.TEXT_NODE
的节点有效。注意,如果观察目标是元素节点,即使该元素包含文本节点,也不会触发此变动类型,除非这些文本节点是被单独观察的。characterDataOldValue: 当文本内容变动时,这个选项会被设置为
true
以捕获变动前的旧值。这个选项仅当characterData
也被设置为true
时有效。attributeOldValue: 当属性变动时,这个选项会被设置为
true
以捕获变动前的旧值。这个选项仅当attributes
也被设置为true
时有效。attributeFilter: 一个数组,包含需要观察变动的属性名称。只有当
attributes
设置为true
时,这个选项才有意义。只有指定的属性发生变动时,才会触发变动回调。
应用场景
开启DOM观察者模式,引爆你的前端开发创造力! - MutationObserverMutationObserver 的 - 掘金
白屏检测
// 创建 MutationObserver 实例
const observer = new MutationObserver((mutationsList) => {// 遍历每个 DOM 变化记录for (const mutation of mutationsList) {// 检查是否是节点的子节点发生了变化if (mutation.type === 'childList') {// 检查页面是否还有子节点if (document.body.childNodes.length === 0) {// 页面处于白屏状态console.log('页面处于白屏状态');} else {// 页面已经加载完成console.log('页面加载完成');}}}
});// 监视整个文档根节点的子节点变化
observer.observe(document.documentElement, {childList: true,subtree: true,
});// 停止监听
// observer.disconnect();
编辑器自动保存
??MutationObserver
在编辑器自动保存场景中可以用于监测编辑器内容的变化,从而实现自动保存功能。通过监听编辑器内容的变化,可以在用户输入或编辑内容时自动触发保存操作,避免用户因意外关闭页面或其他原因导致的数据丢失。
// 目标编辑器元素
const editor = document.getElementById('editor');// 创建 MutationObserver 实例
const observer = new MutationObserver((mutationsList) => {// 编辑器内容发生变化时触发保存操作saveEditorContent();
});// 监视编辑器内容的子节点变化
observer.observe(editor, { childList: true, subtree: true });// 保存编辑器内容的函数
function saveEditorContent() {// 执行保存操作,可以通过 Ajax 请求或其他方式将内容发送到服务器进行保存console.log('正在保存编辑器内容...');
}// 停止监听
// observer.disconnect();
防止水印被删除
? ?MutationObserver
可以用于防止水印被删除的场景,通过监测相关元素的变化,可以检测到水印元素是否被删除或修改,并及时进行恢复。
// 目标水印元素
const watermark = document.getElementById('watermark');// 创建 MutationObserver 实例
const observer = new MutationObserver(() => {// 水印元素发生变化时重新添加水印restoreWatermark();
});// 监视水印元素的父节点变化
observer.observe(watermark.parentNode, { childList: true });// 恢复水印的函数
function restoreWatermark() {// 检查水印元素是否存在,若不存在则重新添加if (!document.contains(watermark)) {// 重新添加水印到目标位置// ...console.log('水印被删除,已恢复');}
}// 停止监听
// observer.disconnect();
实时搜索和过滤
??MutationObserver
在实时搜索和过滤场景中可以用于监测搜索条件的变化,并在每次搜索条件发生变化时触发搜索或过滤操作。通过监听搜索条件的变化,可以及时响应用户的输入,并实时更新搜索结果或过滤列表,提供更好的搜索体验。
// 目标搜索输入框元素
const searchInput = document.getElementById('searchInput');// 创建 MutationObserver 实例
const observer = new MutationObserver(() => {// 搜索条件发生变化时执行搜索或过滤操作performSearch();
});// 监视搜索输入框的值变化
observer.observe(searchInput, { characterData: true, subtree: true });// 搜索或过滤操作的函数
function performSearch() {// 获取搜索输入框的值const searchValue = searchInput.value.trim();// 执行搜索或过滤操作,根据具体需求来实现// ...console.log('Performing search or filter: ' + searchValue);
}// 停止监听
// observer.disconnect();
进阶
- 精确指定目标:在创建
MutationObserver
实例时,明确指定要观察的目标元素,避免过于宽泛的监测范围。这可以提高性能并减少不必要的回调触发。 - 选择合适的观察选项:根据需求选择合适的观察选项。常见的选项包括
childList
(监听子节点的变化)、attributes
(监听属性的变化)、characterData
(监听文本节点内容的变化)等。根据实际情况,只选择需要监测的选项,避免监听不必要的变化。 - 使用
disconnect
方法停止监听:在不再需要监听的时候,调用disconnect
方法停止MutationObserver
的监听。这可以释放资源并避免不必要的回调触发。 - 避免频繁的回调触发:回调函数可能会在短时间内多次触发,尤其是在监测范围较大或有频繁变化的情况下。在回调函数中尽量避免执行耗时操作,以免影响性能。
- 结合其他技术和优化手段:
MutationObserver
可以与其他技术和优化手段结合使用,以实现更好的效果。例如,可以结合Debounce
或Throttle
技术来限制回调函数的触发频率,以减少频繁的回调。 - 浏览器兼容性考虑:
MutationObserver
在大多数现代浏览器中得到支持,但仍需注意浏览器的兼容性。如果需要在旧版本的浏览器中使用MutationObserver
,可以考虑使用polyfill
或其他替代方案。 - 回调函数执行时间:回调函数在每次
DOM
更新之后都会被触发,因此应尽量避免在回调函数中执行耗时操作,以免影响页面的响应性能。 - 无法监测样式变化:
MutationObserver
默认无法监测样式的变化,只能监测到DOM
结构的变化。如果需要监测样式的变化,可以使用CSSOM
或其他技术进行检测。 - 无法监测属性的初始值变化:
MutationObserver
只能监测到属性的后续变化,而无法监测到属性初始值的变化。如果需要监测属性初始值的变化,可以通过其他方法进行检测,如在元素创建之前记录初始值。 - 可能触发多次回调:在某些情况下,
MutationObserver
可能会在短时间内触发多次回调,尤其是当监测范围较大或有频繁的DOM
变化时。因此,在回调函数中应考虑回调的频率和性能消耗,避免执行过多的耗时操作。 - 无法跨域监测和操作:由于浏览器的安全策略限制,
MutationObserver
无法跨域监测和操作DOM
。只能在同域的情况下使用MutationObserver
进行DOM
监测。 - 不支持
IE9
及以下版本:MutationObserver
不支持IE9
及以下版本的浏览器,如果需要在旧版本的浏览器中使用MutationObserver
,可以考虑使用polyfill
或其他替代方案。 - 注意 DOM 修改的影响:在回调函数中对 DOM 进行修改可能会触发新的
DOM
变化,从而再次触发MutationObserver
的回调函数。这可能导致无限循环的情况发生,因此在修改DOM
时要小心谨慎。
ResizeObserver
**??ResizeObserver
**接口监视Element内容盒或边框盒或者SVGElement边界尺寸的变化。
同时无需再手动调用
getBoundingClientRect
来获取元素的尺寸大小,它对任何元素大小变化做出反应,与引起变化的原因无关。通知的内容包含了足够的信息,以便开发者能够根据当前元素的具体大小信息来作出变化,而不是要开发者重新调用getComputedStyle、getBoundingClientRect来获取。
- 监听元素:target。
- contentRect。
- contentBoxSize。
- borderBoxSize。
- devicePixelContentBoxSize。
需要注意的是,虽然只有当 BoxOptions 关心的盒模型变化时才会触发通知,但实际上通知时会将三种不同盒模型下的具体大小都返回给回调函数,用户无需再次手动获取。
window.resize事件能帮我们监听窗口大小的变化。但是reize事件会在一秒内触发将近60次,所以很容易在改变窗口大小时导致性能问题。换句话说,window.resize事件通常是浪费的,因为它会监听每个元素的大小变化(只有window对象才有resize事件),而不是具体到某个元素的变化。如果我们只想监听某个元素的变化的话,这种操作就很浪费性能了。
而ResizeObserver API就可以帮助我们:监听一个DOM节点的变化,这种变化包括但不仅限于:
- 某个节点的出现和隐藏
- 某个节点的大小变化
resize事件只有当 viewport 的大小发生变化时会被触发,元素大小的变化不会触发 resize 事件;并且也只有注册在 window 对象上的回调会在 resize 事件发生时被调用,其他元素上的回调不会被调用。
当「resize」事件发生后,我们往往需要通过调用getBoundingClientRect或者getComputedStyle来获取此时我们关心的元素大小,以此判断元素是否发生了变化。频繁调用getBoundingClientRect、getComputedStyle等 API 会导致「浏览器重排(reflow)」,导致页面性能变差,
API介绍:
- **ResizeObserver.disconnect():**取消特定观察者目标上所有对Element的监听。
- **ResizeObserver.observe():**开始对指定Element的监听。
- 第一个参数为观察的元素。
- 第二个参数为可选参数 BoxOptions,用来指定将以哪种盒子模型来观察变动,如content-box(默认值),border-box和device-pixel-content-box。
- **ResizeObserver.unobserve():**结束对指定Element的监听。
第三方 --resize-observer-polyfill
栗子:使用 resize-observer-polyfill 管理 DOM 变化-JavaScript中文网-JavaScript教程资源分享门户
推荐开源项目:ResizeObserver Polyfill - 窗口尺寸监听解决方案-CSDN博客
举个栗子
const ro = new ResizeObserver(entries => {for (let entry of entries) {entry.target.style.borderRadius = Math.max(0, 250 - entry.contentRect.width) + 'px';}
});ro.observe(document.querySelector('.box'));
应用场景
虚拟列表支持动态高度
响应式广告投放
探索 ResizeObserver 的神奇力量ResizeObserver API 的目标是提供一种高效且准确地监听 D - 掘金
PerformanceObserver
待补充…
参考文献:
探秘神奇的IntersectionObserver:释放网页性能的黑科技!IntersectionObserver 提供 - 掘金
交叉观察器 API - Web API | MDN
尝试使用JS IntersectionObserver让标题和导航联动 ? 张鑫旭-鑫空间-鑫生活
交叉观察器 API - Web API | MDN
JavaScript中最重要的5个Observer,看这一篇就够了_js observer-CSDN博客
开启DOM观察者模式,引爆你的前端开发创造力! - MutationObserverMutationObserver 的 - 掘金
MutationObserver - Web API | MDN
ResizeObserver - Web API | MDN
Resize Observer 介绍及原理浅析-resize-observer-polyfill
一个较新的WEB API——ResizeObserver 的使用今天在看同事代码的时候看见这个API,出于好奇就去了解了 - 掘金
浏览器的 5 种 Observer,你用过几种?网页开发中我们经常要处理用户交互,我们会用 addEventListen - 掘金
相关文章:

web的五个Observer API
IntersectionObserver: 一个元素从不可见到可见,从可见到不可见 ??IntersectionObserver是一种浏览器提供的 JavaScript API,用于监测元素与视窗的交叉状态。它可以告诉开发者一个元素是否进入或离开视窗,以及两者的交叉区域的…...

Java基础:抽象类与接口
1、抽象类和接口的定义: (1)抽象类主要用来抽取子类的通用特性,作为子类的模板,它不能被实例化,只能被用作为子类的超类。 (2)接口是抽象方法的集合,声明了一系列的方法…...

llama.cpp:PC端测试 MobileVLM -- 电脑端部署图生文大模型
llama.cpp:PC端测试 MobileVLM 1.环境需要2.构建项目3.PC测试 1.环境需要 以下是经实验验证可行的环境参考,也可尝试其他版本。 (1)PC:Ubuntu 22.04.4 (2)软件环境:如下表所示 工…...

Web前端基础知识(一)
前端是构建网页的一部分,负责用户在浏览器中看到和与之交互的内容。 网页是在浏览器中呈现内容的文档或页面。 通常,网页使用HTML、CSS、JavaScript(JS)组成。 HTML:定义了页面的结构和内容。包括文本、图像、链接等。 CSS:定义页面的样式…...

基于谱聚类的多模态多目标浣熊优化算法(MMOCOA-SC)求解ZDT1-ZDT4,ZDT6和工程应用--盘式制动器优化,MATLAB代码
一、MMOCOA-SC介绍 基于谱聚类的多模态多目标浣熊优化算法(Multimodal Multi-Objective Coati Optimization Algorithm Based on Spectral Clustering,MMOCOA-SC)是2024年提出的一种多模态多目标优化算法,该算法的核心在于使用谱…...

国标GB28181摄像机接入EasyGBS如何通过流媒体技术提升安防监控效率?
随着信息技术的飞速发展,视频监控技术已成为维护公共安全和提升管理效率的重要手段。国标GB28181作为安防行业的统一设备接入与流媒体传输标准,为视频监控系统的互联互通提供了坚实的基础。EasyGBS作为一款基于GB28181协议的视频云服务平台,通…...

[Unity] ShaderGraph动态修改Keyword Enum,实现不同效果一键切换
上次更新已然四个月前,零零散散的工作结束,终于有时间写点东西记录一下~ 实际使用中,经常会碰到同一个对象需要切换不同的材质,固然可以通过C#直接替换材质球。 或者在ShaderGraph中使用Comparison配合Branch实现切换ÿ…...

Unity开发哪里下载安卓Android-NDK-r21d,外加Android Studio打包实验
NDK下载方法(是r21d,不是r21e, 不是abc, 是d版本呢) google的东西,居然是完全开源的 真的不是很多公司能做到,和那种伪搜索引擎是不同的 到底什么时候google才会开始造车 不过风险很多,最好不要合资,风险更大 Andr…...

FFTW基本概念与安装使用
FFTW基本概念与安装使用 1 基本概念2 编译安装3 使用实例3.1 单线程3.2 多线程 本文主要介绍FFTW库的基本概念、编译安装和使用方法。 1 基本概念 FFTW (Fastest Fourier Transform in the West)是C语言的一个子程序库,用于计算一维或多维离散傅里叶变换(Discrete …...

【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
Hiヽ(゜▽゜ )-欢迎来到蓝染Aizen的CSDN博客~ 🔥 博客主页: 【✨蓝染 の Blog😘】 💖感谢大家点赞👍 收藏⭐ 评论✍ 文章目录 行为型模式1、模板方法模式(1)概述(2&…...

教师如何打造专属私密成绩查询系统?
期末的校园,被一种特殊的氛围所笼罩。老师们如同辛勤的工匠,精心打磨着每一个教学环节。复习阶段,他们在知识的宝库中精挑细选,把一学期的重点内容一一梳理,为学生们打造出系统的复习框架。课堂上,他们激情…...

【1224】C选填(字符串\0占大小,类大小函数调用,const定义常量,逗号表达式取尾,abs返回值
1.设有数组定义: char array[]"China"; 则数组array所占的存储空间为__________ 6 注意要加上\0的位置 数组中考虑‘\0’,sizeof()判断大小也要考虑‘\0’ 2.初始化数组char[] strArray"kuai-shou",strArray的长度为(&am…...

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——终篇
本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——终篇 至此,本系列的所有备赛分享已经结束 首先说说备赛的过程吧,这次比赛,真的是让我学到了太多书本上学不到的东西。一开始,对统筹控制还很模糊&a…...

复合机器人:开启智能制造新时代
在当今科技飞速发展的时代,智能制造已成为制造业转型升级的关键驱动力。而复合机器人作为智能制造领域的一颗璀璨新星,正以其卓越的性能和创新的设计,为各行各业带来前所未有的变革与机遇。 复合机器人,顾名思义,是融…...

装饰者模式
代码详解:【设计模式】Java 设计模式之装饰者模式(Decorator)_java 装饰者模式-CSDN博客 // 抽象构件角色 public interface Component {void operation(); }// 具体构件角色 public class ConcreteComponent implements Component {Override…...

【机器学习】当教育遇上机器学习:打破传统,开启因材施教新时代
我的个人主页 我的领域:人工智能篇,希望能帮助到大家!!!👍点赞 收藏❤ 教育是人类社会发展的基石,然而传统教育模式往往难以满足每个学生的个性化需求。随着机器学习技术的兴起,教…...

【蓝桥杯每日一题】分糖果——DFS
分糖果 蓝桥杯每日一题 2024-12-24 分糖果 DFS 题目描述 两种糖果分别有 9 个和 16 个,要全部分给 7 个小朋友,每个小朋友得到的糖果总数最少为 2 个最多为 5 个,问有多少种不同的分法。糖果必须全部分完。 只要有其中一个小朋友在两种方案中…...

information_schema是什么?
前言 在现代数据驱动的应用开发中,理解和管理数据库结构变得尤为重要。几乎所有的SQL数据库管理系统(DBMS)都提供了一个名为 information_schema 的虚拟数据库。它不仅是一个了解数据库内部结构的强大工具,也是一个实现跨平台兼容…...

案例分析-THC7984设计问题报告
目录 简介 配置信息 结论: 简介 使用的环境 AD芯片:THC7984 VGA信号:通过电脑主机产生1024x768 60HZ信号。 配置信息 AD数字数字产生通过FPGA接收。 AD寄存器配置(第一个数数据,第二个是地址): iic_write_reg 1 0x1e iic_write_reg 02 0x5...

HarmonyOS NEXT 技术实践-基于基础视觉服务的多目标识别
在智能手机、平板和其他智能设备日益智能化的今天,视觉识别技术成为提升用户体验和智能交互的重要手段。HarmonyOS NEXT通过基础视觉服务(HMS Core Vision)提供了一套强大的视觉识别功能,其中多目标识别作为其关键技术之一&#x…...

【python】银行客户流失预测预处理部分,独热编码·标签编码·数据离散化处理·数据筛选·数据分割
数据预处理 通过网盘分享的文件:银行流失预测数据和代码 链接: https://pan.baidu.com/s/1loiB8rMvZArfjJccu4KW6w?pwdpfcs 提取码: pfcs 非数值特征处理 目的:将非数值特征转换为数值型,以便模型能够处理。方法: 地理位置&am…...

使用 docker ps 查不到刚刚创建的容器
问题描述 docker创建mysql容器并实现本地目录挂载,虽然创建成功了,但是查看容器却不存在,删除重新创建还是同样的问题。 原因分析: 因为做本地目录挂载的时候在宿主机中创建了相关文件夹,并且还预先把数据库文件丢…...

vue2+element 前端表格下载
前台下载table表格 可下载fixed columns和普通平铺的表格 exportExcel() {const tableContainer document.querySelector(#table)const fixflg tableContainer ? tableContainer.querySelector(.el-table__fixed) : null// const fixflg document.querySelector(.el-table_…...

MySQL使用LOAD DATA INFILE方式导入文本文件
【图书推荐】《MySQL 9从入门到性能优化(视频教学版)》-CSDN博客 《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…...

【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
文章目录 一、软件下载安装1、Unity官网2、下载Unity Hub 二、修改Unity Hub配置1、设置Unity Hub中文语言2、修改默认存储目录 三、安装unity编辑器1、点击安装编辑器2、版本选择3、关于版本号4、安装模块选择5、等待下载完成自动安装即可6、追加unity和模块 四、许可证管理专…...

SpringBootWeb 篇-深入了解 SpringBoot + Vue 的前后端分离项目部署上线与 Nginx 配置文件结构
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 云服务器的准备 2.0 Xshell 和 Xftp 软件 2.1 Xshell 介绍 2.2 Xftp 介绍 3.0 在云服务器进行环境配置 3.1 安装 JDK 3.2 安装 MySQL 3.3 安装 Nginx 4.0 SpringB…...

优化程序中的数据:从代数到向量解
前言 在前文笔者简单介绍了把数据迭代抽象为线性代数,并介绍了空间体、维度等概念。 数据复用 数据复用是一种提高程序执行效率与数据局部性的方法,分为自复用与组复用, 自复用:如果多个迭代访问同一个内存位置,那…...

【Web】2024“国城杯”网络安全挑战大赛决赛题解(全)
最近在忙联通的安全准入测试,很少有时间看CTF了,今晚抽点时间回顾下上周线下的题(期末还没开始复习😢) 感觉做渗透测试一半的时间在和甲方掰扯&水垃圾洞,没啥惊喜感,还是CTF有意思 目录 Mountain ez_zhuawa 图…...

基于ceres优化的3d激光雷达开源算法
以下是一些基于CERES优化的开源激光雷达SLAM或相关算法: (1) LOAM (Lidar Odometry And Mapping) 简介: LOAM是一种经典的激光雷达里程计和建图算法,它通过提取特征点(角点和平面点),利用ICP(Iterative Cl…...

【FAQ】HarmonyOS SDK 闭源开放能力 — Vision Kit(2)
1.问题描述: 人脸活体检测返回上一页App由沉浸式变为非沉浸式多了上下安全区域。 解决方案: 检测结束后需要自己去设置沉浸式配置。 2.问题描述: Vision Kit文字识别是本地识别,还是上传至服务器,由服务器来识别文…...