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

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);
...

用文字解释下就是这两步:

  1. 定义元素交叉后干嘛干嘛;
  2. 需要观察那些元素;

实际开发的时候,主要工作就是对entries.forEach这部分的代码进行处理。

应用场景

探秘神奇的IntersectionObserver:释放网页性能的黑科技!IntersectionObserver 提供 - 掘金

图片懒加载

通过使用IntersectionObserver,可以延迟加载图片,只在它们进入视窗时才开始加载。这样可以减少初始页面加载时间,并节省带宽和资源。

实现图片懒加载的步骤如下:

  1. 创建IntersectionObserver实例,并指定观察的目标元素。
  2. 在回调函数中,判断目标元素是否进入视窗。
  3. 若目标元素进入视窗,将其真实的图片地址赋给元素的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秒以上时,被认为用户对该元素感兴趣。

步骤如下:

  1. 创建 IntersectionObserver 实例,并指定观察的目标元素。
  2. 在回调函数中,根据目标元素的交叉状态判断用户对该元素的兴趣。
  3. 根据规则判断适口停留时间是否满足条件。
  4. 如果满足条件,则记录兴趣数据或触发相应操作。
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,但在一些旧版本浏览器中可能不被支持。为了确保兼容性,可以使用 IntersectionObserverpolyfill 或提供降级方案。
  • 处理 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对象在MutationObserverobserve方法中用于指定哪些类型的 DOM 变动需要被观察config对象可以包含以下属性,每个属性都是一个布尔值,指示是否应该观察对应类型的变动:

  1. attributes: 当被观察元素的属性变动时触发。注意,这个选项不会捕获class属性的变动,除非通过attributeNameFilter明确指定。要捕获class属性的变动,可以监视attributeFilter['class'],或者使用子树变动(childList)和特性变动(attributes)的组合,因为类名的变化通常会导致子节点(如span元素,用于通过 CSS 类应用样式)的添加或移除。

  2. childList: 当被观察元素的子节点变动时触发(添加或移除子节点)。

  3. subtree: 当被观察元素的所有后代节点变动时触发。这个选项扩大了观察范围,使得变动不仅限于直接子节点,还包括所有更深层次的子节点。

  4. characterData: 当被观察元素的文本内容变动时触发。这个选项仅对文本节点或设置了nodeTypeNode.TEXT_NODE的节点有效。注意,如果观察目标是元素节点,即使该元素包含文本节点,也不会触发此变动类型,除非这些文本节点是被单独观察的。

  5. characterDataOldValue: 当文本内容变动时,这个选项会被设置为true以捕获变动前的旧值。这个选项仅当characterData也被设置为true时有效。

  6. attributeOldValue: 当属性变动时,这个选项会被设置为true以捕获变动前的旧值。这个选项仅当attributes也被设置为true时有效。

  7. 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 可以与其他技术和优化手段结合使用,以实现更好的效果。例如,可以结合 DebounceThrottle 技术来限制回调函数的触发频率,以减少频繁的回调。
  • 浏览器兼容性考虑: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节点的变化,这种变化包括但不仅限于:

  1. 某个节点的出现和隐藏
  2. 某个节点的大小变化

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&#xff1a; 一个元素从不可见到可见&#xff0c;从可见到不可见 ??IntersectionObserver是一种浏览器提供的 JavaScript API&#xff0c;用于监测元素与视窗的交叉状态。它可以告诉开发者一个元素是否进入或离开视窗&#xff0c;以及两者的交叉区域的…...

CSS学习记录19

CSS文本效果 CSS text-overflow 属性规定应如何向用户呈现未显示的溢出的内容。 //裁剪 text-overflow: clip; //隐藏 text-overflow: ellipsis; CSS字换行&#xff08;Word Wrapping&#xff09; CSS word-wrap 属性使长文字能够被折断并换到下一行。 如果一个单词太长而…...

使用Amazon Bedrock的无服务器的智能工作流

使用Amazon Bedrock的无服务器的智能工作流 智能工作流基于用户输入处理不可预见的任务&#xff0c;比如发起API调用。无服务器架构可以高效地管理这些任务和不同的工作负载&#xff0c;而无需维护服务器&#xff0c;从而加快部署速度。 你将学习如何通过使用带有保护措施的智能…...

SDMTSP:粒子群优化算法PSO求解单仓库多旅行商问题,可以更改数据集和起点(MATLAB代码)

一、单仓库多旅行商问题 单仓库多旅行商问题&#xff08;Single-Depot Multiple Travelling Salesman Problem, SD-MTSP&#xff09;&#xff1a;&#x1d45a;个推销员从同一座中心城市出发&#xff0c;访问其中一定数量的城市并且每座城市只能被某一个推销员访问一次&#x…...

Java中的访问修饰符:分类、作用及应用场景

在Java编程中&#xff0c;访问修饰符&#xff08;Access Modifiers&#xff09;是控制类、方法、变量和构造函数访问权限的关键工具。通过合理使用访问修饰符&#xff0c;可以有效地封装代码&#xff0c;保护数据&#xff0c;并确保代码的安全性和可维护性。本文将详细介绍Java…...

【day16】Java开发常用API

模块15回顾 在深入探讨模块16之前&#xff0c;让我们回顾一下【day15】中的重点内容&#xff1a; String类&#xff1a; 构造方法&#xff1a;String(), String(String s), String(char[] chars), String(byte[] bytes), String(char[] chars, int offset, int count), String…...

LLaMA-Factory(二)界面解析

这里写目录标题 1. 基础选项语言模型选择模型路径微调方法检查点路径量化等级量化方法提示模板RoPE加速方式 2.模型训练界面训练方式数据集超参数设置其他参数部分参数设置LoRA参数设置RLHF参数设置GaLore参数设置BAdam参数设置训练 3.评估预测界面4.Chat界面5.导出Export界面 …...

(14)CT137A- 动态数码管设计

&#xff08;1&#xff09;了解板卡原理图中数码管的特性&#xff1a;共阳极数码管&#xff0c;公共端连接了电源&#xff0c;FPGA IO口低电平有效&#xff0c;另外&#xff0c;可以看到位选端FPGA位选低电平时选通。 &#xff08;2&#xff09;刷新时间的设定&#xff1a;众所…...

RT-DETR学习笔记(2)

七、IOU-aware query selection 下图是原始DETR。content query 是初始化为0的label embedding, position query 是通过nn.Embedding初始化的一个嵌入矩阵&#xff0c;这两部分没有任何的先验信息&#xff0c;导致DETR的收敛慢。 RT-DETR则提出要给这两部分&#xff08;conten…...

JS、JSX 和 TSX 的对比指南

JS、JSX 和 TSX 的对比指南 1. JavaScript (.js) 简介 JavaScript 是一种轻量级的、解释型的编程语言&#xff0c;是 Web 开发中最基础的语言之一。 优点 学习曲线较低&#xff0c;容易入门使用范围广泛&#xff0c;生态系统成熟灵活性高&#xff0c;支持多种编程范式不需…...

【STM32】RTT-Studio中HAL库开发教程十:EC800M-4G模块使用

文章目录 一、简介二、模块测试三、OneNet物联网配置四、完整代码五、测试验证 一、简介 EC800M4G是一款4G模块&#xff0c;本次实验主要是进行互联网的测试&#xff0c;模块测试&#xff0c;以及如何配置ONENET设备的相关参数&#xff0c;以及使用STM32F4来测试模块的数据上报…...

增加nginx配置文件(conf.d), 管理多个项目

1.切换到nginx目录下, 新建conf.d文件夹 mkdir conf.d 2.赋予conf.d权限 chmod 777 conf.d 3.进入conf.d, 编辑conf文件 vim zc_travel.conf server { listen 13101; server_name localhost;location / {root /home/baoxin/app/web/insight-radar-rcfx-pre/html_dev;index …...

服务器中了挖矿病毒-应急响应

事件&#xff1a;客户反映服务器响应很慢&#xff0c;出行卡顿&#xff0c;服务器操作系统为windows server 2008。 现场解决步骤&#xff1a; 1、打开任务管理器&#xff0c;看到一个javs.exe的程序&#xff0c;占用CPU使用率比较高&#xff0c;怀疑可能是木马。 2、右键打开…...

pid学习感悟

飞行控制PID算法——无人机飞控_飞控算法-CSDN博客 首先pid是对现测量值和目标值的差值&#xff0c;即偏差值的操作 p是线性操作&#xff0c;偏差越大&#xff0c;则对于控制单元操作的值越大 d是微分操作&#xff0c;我们知道微分其实就是数值变化的斜率&#xff0c;所以当偏…...

Centos7.9安装openldap+phpldapadmin+grafana配置LDAP登录最详细步骤 亲测100%能行

一、部署LDAP 1、安装LDAP yum install -y openldap-servers openldap-clients openldap openldap-devel compat-openldap openldap-servers-sql systemctl start slapd systemctl enable slapd2、创建第一个管理账号密码&#xff08;设置为ldapadmin&#xff09; slappass…...

唯品会C++面试题及参考答案

内存池怎么可以保证不会产生碎片? 内存池通过预先分配一块较大的内存区域,然后对这块内存进行管理,来减少碎片产生。 首先,内存池采用固定大小的内存块分配策略。比如,将内存池划分成大小相同的小块,当有内存分配请求时,就从这些固定大小的块中选取合适的进行分配。这种…...

Flask中@app.route()的methods参数详解

诸神缄默不语-个人CSDN博文目录 在 Flask 中&#xff0c;app.route 是用于定义路由的核心装饰器&#xff0c;开发者可以通过它为应用指定 URL 映射及相应的处理函数。在处理 HTTP 请求时&#xff0c;不同的业务场景需要支持不同的 HTTP 方法&#xff0c;而 app.route 的 metho…...

使用Grafana中按钮插件实现收发HTTP请求

最近项目中需要监控分布式集群的各项指标信息&#xff0c;需要用到PrometheusGrafana的技术栈实现对分布式集群的各个节点状态进行可视化显示&#xff0c;但是要求前端需要提供一个易用的接口让用户可以触发一些操作&#xff0c;例如负载高时进行负载均衡或弹性伸缩。网上找到的…...

workman服务端开发模式-应用开发-vue-element-admin挂载websocket

一、项目根目录main.js添加全局引入 import /utils/websocket 二、在根目录app.vue 中初始化WebSocket连接 <template><div id"app"><router-view /></div> </template><script>import store from ./store export default {n…...

堆排序【东北大学oj数据结构9-4】C++

堆排序是一种基于堆的数据结构的排序&#xff0c;是一种快速排序算法&#xff0c;可以在输入数组中实现排序处理&#xff08;内存高效&#xff09;。 堆排序可以实现如下&#xff1a; maxHeapify(A, i) l left(i) r right(i) // select the node which has the m…...

Linux RTC 驱动框架

目录 一、实时时钟&#xff08;RTC&#xff09;介绍1.1 概述1.2 功能1.3 应用场景1.4 工作原理1.5 对外接口1.6 常见 RTC 芯片1.7 在 Linux 系统中的应用1.8 注意事项 二、Linux 内核 RTC 驱动框架2.1 相关源码文件介绍2.2 核心数据结构2.2.1 struct rtc_device2.2.2 rtc_class…...

智能订餐:基于JSP的管理系统设计与优化

相关技术介绍 2.1 B/S结构 目前使用较多的开发结构模式大致可以包括C/S模式和B/S模式[5]。其中&#xff0c;C/S模式全称为客户端/服务器模式&#xff08;Client/Server模式&#xff09;&#xff0c;B/S模式全称为浏览器/服务器模式&#xff08;Browser/Server模式&#xff09;。…...

Java基本查询(四)

JPA 查询All示例 JPA教程 - JPA查询All示例 我们可以在JPQL中使用带有子查询的ALL运算符。 List l em.createQuery("SELECT e FROM Professor e WHERE e.salary < " "ALL (SELECT d.salary FROM e.directs d)").getResultList();例子 下面的代码来自…...

【双指针算法】--复写零

文章目录 1. 题目2. 题目解析3. 代码 1. 题目 在线oj 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&#xff1a;请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改&a…...

leetcode hot100 两两交换链表之中的节点

24. 两两交换链表中的节点 已解答 中等 相关标签 相关企业 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09; # Definition fo…...

Yolo11改进策略:主干网络改进|FastVit与Yolo11完美融合,重参数重构Yolo11网络(全网首发)

文章目录 摘要FastViT:一种使用结构重新参数化的快速混合视觉变换器1、简介2、相关工作3、体系结构3.1、概述3.2、FastViT3.2.1、重新参数化跳过连接3.2.2、线性训练时间过参数化3.2.3、大核卷积4、实验4.1、图像分类4.2、鲁棒性评价4.3、3D Hand网格估计4.4、语义分割和目标检…...

vscode打开下一个文件的时候上一个文件会关闭

解决方法&#xff1a; 你可以通过设置 workbench.editor.enablePreview 来控制在 VS Code 中打开文件时是否会关闭上一个文件。将其设置为 false 可以防止这种行为。 {"workbench.editor.enablePreview": false } 在设置编辑器中显示 "workbench.editor.enab…...

windows使用zip包安装MySQL

windows通过zip包安装MySQL windows通过zip包安装MySQL下载MySQL的zip安装包创建安装目录和数据目录解压zip安装包创建配置目录 etc 和 配置文件 my.ini安装MySQL进入解压后的bin目录执行命令初始化执行命令安装 验证安装查看服务已安装 启动MySQL查看服务运行情况修改密码创建…...

【LeetCode每日一题】——415.字符串相加

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 字符串 二【题目难度】 简单 三【题目编号】 415.字符串相加 四【题目描述】 给定两个字符…...

基于角色的访问控制(RBAC)在异构系统中的应用

在数字化蓬勃发展的当下&#xff0c;企业运营高度依赖各类异构系统。基于角色的访问控制&#xff08;RBAC&#xff09;成为管理这些系统中用户权限的核心策略。RBAC 依据组织内的岗位、职责定义角色&#xff0c;按角色分配权限&#xff0c;用户凭借所属角色获取相应访问权&…...

FPGA实现MIPI转FPD-Link车载同轴视频传输方案,基于IMX327+FPD953架构,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、详细设计方案设计原理框图IMX327 及其配置FPD-Link视频串化-解串方案MIPI CSI RX图像 ISP 处理图像缓存HDMI输出工程源码架构 5、…...

远程控制macOS一直卡在100%,能连接上了却只显示了壁纸?

前言 前段时间有个朋友过来咨询关于Windows使用第三方远程软件&#xff08;向日葵、Todesk等&#xff09;远程连接控制macOS系统&#xff0c;但出现了一些奇奇怪怪的问题。 比如在连接的时候&#xff0c;一直卡在100%连接&#xff0c;对方的电脑却已经显示已经被控制的状态。…...

springboot中使用gdal将表中的空间数据转shapefile文件

springboot中使用gdal将表中的空间数据转shapefile文件 代码&#xff1a; // 样本导出-将样本表导出为shapefile&#xff0c;复制样本shp文件到临时目录下 sampleDir是文件夹pathpublic void setYbShapeFile(Yb yb, File sampleDir) {// 创建 前时项 和 后时项 文件夹File y…...

捋一捋相关性运算,以及DTD和NLP中的应用

捋一捋相关性运算&#xff0c;以及DTD和NLP中的应用 相关性和相干性,有木有傻傻分不清相关性数字信号的相关运算同维度信号的相关理解 相关--互相关--相干 回声消除过程如何套用这些知识相关性/相干性检测在DT中的应用参考 相关性和相干性,有木有傻傻分不清 这是容易混淆的两个…...

Calcite Web 项目常见问题解决方案

Calcite Web 项目常见问题解决方案 calcite-web Authoritative front-end development resources for Calcite design initiative. Includes extendable base components and styles, as well as a modular and efficient framework for ArcGIS properties. [这里是图片001] 项…...

3090. 每个字符最多出现两次的最长子字符串

题目内容&#xff1a; 给你一个字符串 s &#xff0c;请找出满足每个字符最多出现两次的最长子字符串&#xff0c;并返回该 子字符串 的 最大 长度。 示例 1&#xff1a; 输入&#xff1a; s "bcbbbcba" 输出&#xff1a; 4 解释&#xff1a; 以下子字符串长…...

基于微信小程序的短视频系统(SpringBoot)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

Git的简介

文章目录 一.Git是什么二.核心概念三.工作流程四.Git的优势 下载Git 推荐官网下载 官网地址 一.Git是什么 Git是一个分布式版本控制系统&#xff0c;用于跟踪文件的变化并协调多人对同一项目的开发工作。它就像是一个时光机器&#xff0c;能够记录文件在不同时间点的状态&…...

【XR】ATW

异步时间扭曲&#xff08;Asynchronous Timewarp&#xff0c;简称ATW&#xff09;是一种在虚拟现实&#xff08;VR&#xff09;技术中使用的算法&#xff0c;它通过生成中间帧来减少因帧率不足导致的抖动和延迟&#xff0c;从而提高用户体验。ATW技术在两个线程中完成时间扭曲的…...

记Fastjson2的一个报ConcurrentModificationException的bug

错误背景&#xff1a;fastjson2的parseObject方法&#xff0c;在spring webflux项目中被调用&#xff0c;有时会报java.util.ConcurrentModificationException错误。报错处的代码如下图&#xff1a; 改了半天与并发安全相关的代码&#xff0c;还是会报此错误。后来改变思路搜…...

JAVAweb学习日记(二)JavaScript

一、概念 二、JavaScript引入方式 三、JavaScript书写语法 输出语句&#xff1a; 变量&#xff1a; 数据类型、运算符、流程控制语句&#xff1a; 数据类型&#xff1a; 运算符&#xff1a; 字符串如果是 数字字符构成&#xff0c;先把读到的数字转为数字类型&#xff0c;后续…...

FPGA学习(基于小梅哥Xilinx FPGA)学习笔记

文章目录 一、整个工程的流程二、基于Vivado的FPGA开发流程实践&#xff08;二选一多路器&#xff09;什么是二选一多路器用verilog语言&#xff0c;Vivado软件进行该电路实现1、设计输入&#xff1a;Design Sources中的代码2、分析和综合&#xff1a;分析设计输入中是否有错误…...

Linux的VIM基本操作

编辑模式转换 编辑指令 linux用vim编辑代码&#xff0c;再用gcc进行编译 编辑命令如下 gcc编译如下...

2024年12月英语六级CET6写作与翻译笔记

目录 1 写作 1.1 大学为学生提供了探索各种可能性 1.2 自律在个人成长中的重要性 1.3 切实可行的目标 2 翻译 2.1 洋山港(Yangshan Port) 2.2 中国航天事业 2.3 北斗卫星导航系统 1 写作 1.1 大学为学生提供了探索各种可能性 1.2 自律在个人成长中的重要性 1.3 切实可…...

学习记录:electron主进程与渲染进程直接的通信示例【开箱即用】

electron主进程与渲染进程直接的通信示例 1. 背景&#xff1a; electronvue实现桌面应用开发 2.异步模式 2.1使用.send 和.on的方式 preload.js中代码示例&#xff1a; const { contextBridge, ipcRenderer} require(electron);// 暴露通信接口 contextBridge.exposeInMa…...

领域自适应

领域自适应&#xff08;Domain Adaptation&#xff09;是一种技术&#xff0c;用于将机器学习模型从一个数据分布&#xff08;源域&#xff09;迁移到另一个数据分布&#xff08;目标域&#xff09;。这在源数据和目标数据具有不同特征分布但任务相同的情况下特别有用。领域自适…...

Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)

KubeadmContainerd部署k8s(v1.28.2)集群&#xff08;非高可用版&#xff09; 文章目录 KubeadmContainerd部署k8s(v1.28.2)集群&#xff08;非高可用版&#xff09;一.环境准备1.服务器准备2.环境配置3.设置主机名4.修改国内镜像源地址5.配置时间同步6.配置内核转发及网桥过滤 …...

重温设计模式--职责链模式

文章目录 职责链模式的详细介绍C 代码示例C示例代码2 职责链模式的详细介绍 定义与概念 职责链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它旨在将请求的发送者和多个接收者解耦&#xff0c;让多个对象都有机会处理请求&a…...

单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号

一&#xff0c;简介 一般来说&#xff0c;公司有很多系统使用&#xff0c;为了实现统一的用户名管理和登录所有系统&#xff08;如 GitLab、Harbor 等&#xff09;&#xff0c;并在员工离职时只需删除一个主账号即可实现权限清除&#xff0c;可以采用 单点登录 (SSO) 和 集中式…...

【Rust自学】5.1. 定义并实例化struct

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 5.1.1. 什么是struct struct的中文意思为结构体&#xff0c;它是一种自定义的数据类型&#xff0c;它允许程序为相关联的值命名和打包&am…...