九、浏览器事件机制

上一篇👉: 浏览器同源策略

目录

  • 浏览器事件机制
    • 1.事件概念及模型
        • 事件模型
    • 2.事件冒泡
    • 3.事件委托
      • (1)事件委托的概念
      • (2)事件委托的特点
      • (3)局限性
      • (4)优化建议
      • 使用场景示例
    • 4.同步和异步的区别
      • **同步(Synchronous)**
      • **异步(Asynchronous)**
      • 概括对比
    • 5.对事件循环的理解
    • 6. 事件触发过程详解
        • 1. **捕获阶段(Capturing Phase)**
        • 2. **目标阶段(Target Phase)**
        • 3. **冒泡阶段(Bubbling Phase)**
        • 特殊情况
        • `addEventListener`方法参数
        • 阻止事件传播
        • 示例代码
    • 7.宏任务和微任务
      • 微任务(Microtasks)
      • 宏任务(Macrotasks)
    • 8. 什么是执行栈
      • 执行栈的工作原理
      • 1. 函数调用
        • 2. 函数执行
        • 3. 函数返回
      • 实际应用中的体现
        • 错误追踪
        • 递归与栈溢出
      • 理解执行栈的重要性
    • 9. Node 中的 Event Loop 和浏览器中的有什么区别
      • Node.js 中的 Event Loop 阶段
      • 浏览器中的 Event Loop

浏览器事件机制

事件是浏览器中一种重要的交互机制,它允许JavaScript响应用户操作(如点击、移动鼠标)或页面自身的状态变化(如加载完成、滚动)。事件处理是前端开发中的基础,理解事件模型对于构建动态和交互式网页至关重要。

1.事件概念及模型

  • 事件(Event):用户与网页交互(如点击按钮)或网页状态改变(如页面加载完毕)时触发的行为。
  • 事件对象(Event Object):每当事件发生时,浏览器都会创建一个事件对象,封装了事件相关的详细信息,如事件类型(click、mousemove)、事件目标(触发事件的元素)、事件时间戳等,还提供了阻止默认行为(preventDefault())和阻止事件传播(stopPropagation())等方法。
事件模型

浏览器普遍支持以下三种事件模型:

  1. DOM0级事件模型
  • 特点:最简单的事件处理方式,直接将事件处理函数赋值给元素的事件属性。如element.onclick = function() {…};
  • 传播:不存在事件流(即捕获和冒泡阶段),事件直接在目标元素上触发。
  • 兼容性:所有浏览器均支持,但功能有限,不能同时绑定多个相同类型的事件处理器。
  1. IE事件模型(也称为DOM1级事件模型)
  • 特点:通过element.attachEvent(‘on[eventName]’, handler);来添加事件监听器。
  • 事件流:分为两个阶段:事件处理阶段(先触发目标元素的事件处理函数),然后是事件冒泡阶段(从目标元素开始,向外层元素传播)。
  • 兼容性:主要是旧版IE浏览器支持,现代浏览器已逐渐弃用。
  1. DOM2级事件模型
  • 特点:引入了addEventListener和removeEventListener方法来添加和移除事件监听器,支持事件捕获、目标、冒泡三个阶段。
  • 事件流:
    • 捕获阶段:从根节点开始,逐层向下直到目标元素,检查是否有对应的捕获阶段事件处理函数。
    • 目标阶段:到达目标元素,触发该元素的事件处理函数。
    • 冒泡阶段:从目标元素开始,逐层向上,直至文档根节点,触发沿途元素的冒泡阶段事件处理函数。
  • 参数:addEventListener接受三个参数,分别为事件类型、处理函数和一个布尔值(true表示在捕获阶段触发,false表示在冒泡阶段触发,默认为false)。
  • 兼容性:所有现代浏览器均支持,是目前推荐使用的事件模型。

DOM2级事件模型提供了更为灵活和强大的事件处理能力,支持事件捕获、目标和冒泡三个阶段,是开发复杂交互应用的首选模型。

2.事件冒泡

在处理浏览器事件时,阻止事件冒泡是控制事件流向、避免不必要的父元素响应事件的一种常见需求。不同浏览器(主要是IE与其他标准浏览器)在实现上有所不同,下面是阻止事件冒泡的两种通用方法:

对于W3C标准浏览器(如Chrome、Firefox、Safari和Edge等)
使用event.stopPropagation()方法。此方法属于DOM Level 2事件模型的一部分,可以在事件处理函数内部调用,以阻止当前事件向上冒泡到父元素。

element.addEventListener('click', function(event) {
    event.stopPropagation(); // 阻止事件向上冒泡
    // 你的事件处理逻辑
}, false);

对于Internet Explorer(特别是IE8及以下版本) IE已经再见了👉: 微软IE浏览器于6月15日正式停止支持
由于早期版本的IE不完全支持W3C的事件模型,需要使用event.cancelBubble属性来阻止事件冒泡。

element.attachEvent('onclick', function(event) {
    event = event || window.event; // 兼容性处理,确保event存在
    event.cancelBubble = true; // 阻止事件冒泡
    // 你的事件处理逻辑
});

兼容性处理:在实际开发中,为了确保跨浏览器兼容性,通常会同时使用这两种方法:

function stopEventBubble(e) {
    e = e || window.event; // 兼容性处理
    if (e.stopPropagation) { // W3C标准方法
        e.stopPropagation();
    } else { // IE兼容性
        e.cancelBubble = true;
    }
}

// 绑定事件
var element = document.getElementById('yourElement');
if (element.addEventListener) {
    element.addEventListener('click', function(e) {
        stopEventBubble(e);
        // 事件处理逻辑
    }, false);
} else if (element.attachEvent) {
    element.attachEvent('onclick', function(e) {
        stopEventBubble(e);
        // 事件处理逻辑
    });
}

3.事件委托

事件委托是一种JavaScript编程技巧,它充分利用了DOM事件流(特别是事件冒泡阶段)的特性,允许开发者在父元素上一次性为多个子元素绑定事件处理器,而不是在每个子元素上单独绑定。以下是您所提供内容的整理和补充,以便更好地理解事件委托的概念、特点、局限性及使用场景

(1)事件委托的概念

事件委托的核心思想在于,当事件在DOM树中从目标元素向上逐级传播(即事件冒泡)时,父元素可以捕捉到这些事件,并通过检查事件的实际目标(event.target)来决定是否执行特定的处理逻辑。这种方法可以减少事件监听器的数量,提高页面性能,尤其是处理大量动态生成的元素时非常有用。

(2)事件委托的特点

  • 减少内存消耗:避免了为大量子元素单独绑定事件处理器,从而节省内存资源。
  • 动态绑定事件:适用于动态添加或删除子元素的场景,无需为新添加的元素手动绑定事件处理器,也不需要在元素移除时清理监听器。
  • 灵活性与可扩展性:通过在事件处理函数中判断目标元素,可以实现更加灵活的事件处理逻辑,易于维护和扩展。

(3)局限性

  • 不适用于无事件冒泡的事件,例如focus和blur。
  • 对于频繁触发且需要精确位置计算的事件(如mousemove),直接在目标元素上绑定事件可能更优,以避免每次事件触发时遍历DOM带来的性能开销。
  • 使用不当可能会影响页面性能,尤其是在深度嵌套的DOM结构中频繁使用事件委托或绑定过多的事件处理器

(4)优化建议

  • 限制使用范围:仅在确实需要的场景应用事件针对性委托,如频繁更新的动态内容区域。
  • 减少层级深度:尽量将事件处理器绑定在靠近目标元素的父级上,避免在body或document级别绑定过多事件。
  • 合并事件处理:将多个事件类型或逻辑相近的处理逻辑合并到同一个事件委托中,通过检查事件类型或目标元素等条件分发处理,减少事件监听器的数量。

使用场景示例

考虑一个需求,需要给页面中所有<a>标签添加点击事件。直接在每个<a>上绑定事件处理器不仅繁琐,而且对于动态添加的链接无效。采用事件委托的方式,可以在document或一个包含所有链接的共同父元素上设置一个监听器,检查触发事件的目标元素是否为<a>标签,如果是,则执行相应的操作。这样既简化了管理,又支持了动态内容的事件处理。

document.addEventListener("click", function(e) {
    var node = e.target;
    while (node !== document) { // 更改为 document 以确保最终跳出循环
        if (node.nodeName === "A") {
            console.log("a clicked");
            break;
        }
        node = node.parentNode;
    }
}, false);

这段代码展示了如何在点击事件发生时,从触发事件的元素开始,逐级向上遍历其父元素直至document,检查途中是否遇到了<a>元素,并作出相应处理。这正是事件委托机制的典型应用。

4.同步和异步的区别

同步(Synchronous)

在同步操作情境下,进程在执行某项请求时,若该请求需要一定时间来完成,进程会直接等待这个请求的结果返回,之后才继续执行接下来的任务。简而言之,同步执行保证了操作的顺序执行,但可能引起等待期间的效率问题。

异步(Asynchronous)

相比之下,异步处理方式则允许进程在发起一个可能耗时的操作后,无需等待其完成,即可继续执行后续代码。当该操作最终完成时,系统将以事件、回调、Promise或async/await等方式通知进程,进程随后在适当时间点处理完成事件的结果。异步机制提高了程序的并发能力和响应速度,尽管它要求更复杂的编程模型来管理任务的非顺序完成。

概括对比

  • 同步确保操作按序执行,简单直观,但可能导致程序在I/O等操作上阻塞等待。
  • 异步通过非阻塞执行优化了资源利用和响应时间,适合处理耗时任务,但增加了编程逻辑的复杂性。

5.对事件循环的理解

JavaScript的事件循环(Event Loop)机制是其异步编程模型的核心,它确保了单线程环境下能够高效处理异步操作而不阻塞主线程。

JavaScript引擎的执行环境基于以下主要组件运作:

  • 执行栈(Call Stack):保存当前执行的函数调用信息,遵循后进先出(LIFO)原则。
  • 任务队列(Task Queues):分为两大类,宏任务(Macrotask)队列和微任务(Microtask)队列。异步操作完成后,其回调会被推入相应的队列。
  • 事件循环(Event Loop):负责监控执行栈和任务队列,当执行栈为空时,从队列中取出任务执行。

事件循环执行步骤

  1. 执行全局脚本:这是第一个宏任务,包括所有同步代码。
  2. 检查微任务队列:执行完当前宏任务后,事件循环会检查微任务队列。如果有微任务,全部执行完毕后再继续。微任务包括:Promise的回调、MutationObserver、process.nextTick(Node.js)等。
  3. 渲染页面(可选):在某些环境中,如浏览器,在一个宏任务周期结束且所有微任务执行完毕后,有机会进行UI渲染。
  4. 执行宏任务:从宏任务队列中取出下一个任务执行。常见的宏任务来源有:setTimeout、setInterval、I/O、UI渲染更新、script(整体代码)等。
  5. 重复循环:上述过程构成一个事件循环周期,不断重复,直到宏任务和微任务队列均为空,或浏览器/Node.js环境决定终止。
执行全局脚本
有微任务吗?
执行宏任务
需要渲染页面吗?
事件循环结束?
退出
执行微任务

重要点强调

  • 微任务优先级高于宏任务:在一个宏任务结束后,会立即执行完当前所有的微任务,然后再执行下一个宏任务。
  • 避免微任务滥用:虽然微任务能实现快速响应,但过度使用或复杂的微任务链可能会导致页面冻结或性能问题。
  • 渲染机会:在事件循环中,页面渲染通常发生在每个宏任务结束且微任务队列清空之后,但这取决于具体的JavaScript运行环境(如浏览器)。

6. 事件触发过程详解

事件在DOM中的传播遵循三个明确的阶段:

1. 捕获阶段(Capturing Phase)
  • 事件从Window对象开始,沿着DOM树向下传播至目标元素。沿途注册了捕获阶段事件监听器的元素将按顺序触发这些监听器。
2. 目标阶段(Target Phase)
  • 事件到达目标元素,触发该元素上所有注册的事件监听器,无论是捕获、目标还是冒泡阶段的监听器。
3. 冒泡阶段(Bubbling Phase)
  • 事件从目标元素开始,反向传播回DOM树的顶层(Window对象)。这一路上,所有注册了冒泡阶段事件监听器的元素都将触发这些监听器。
特殊情况
  • 若在同一个元素上同时注册了冒泡和捕获事件,它们的触发顺序遵循注册的顺序,而不是严格按照捕获->目标->冒泡的阶段划分。
addEventListener方法参数
  • 第三个参数决定事件处理的阶段:
    • 布尔值true表示捕获阶段,false或省略默认为冒泡阶段。
    • 对象:提供更多选项,如:
      • capture: 类似布尔值参数,指定事件是否在捕获阶段触发。
      • once: 设为true,监听器只执行一次后即被移除。
      • passive: 设为true,表明监听器永远不会调用preventDefault
阻止事件传播
  • event.stopPropagation():阻止事件在当前阶段继续向上或向下传播,不影响同阶段内其他监听器。
  • event.stopImmediatePropagation():不仅阻止事件传播,还阻止目标元素上其他相同类型的事件监听器执行。
示例代码
// 先打印"冒泡",再打印"捕获"
const node = document.querySelector('#someNode');
node.addEventListener('click', event => console.log('冒泡'), false);
node.addEventListener('click', event => console.log('捕获'), true);

// 使用 `stopImmediatePropagation` 阻止其他相同事件触发
node.addEventListener('click', event => {
    event.stopImmediatePropagation();
    console.log('仅此一次');
}, false);

// 即使点击,也不会执行下方的监听器,因为上方的已阻止
node.addEventListener('click', event => console.log('不会执行'), false);

7.宏任务和微任务

微任务(Microtasks)

微任务在当前执行栈结束后,且浏览器渲染前执行,具有较高优先级,确保快速处理与响应。主要包括:

  • Promise 回调

  • Promise 状态从 pending 变为 fulfilledrejected 时,触发的 .then.catch.finally 回调函数。

  • Node.js 中的 process.nextTick

    • 用于将回调函数推迟到当前执行栈的末尾,但仍在下一个事件循环迭代开始前执行。
  • DOM 变更观察(MutationObserver)

    • 监听 DOM 树结构变化,并在变化发生后执行注册的回调函数。

宏任务(Macrotasks)

宏任务构成了 JavaScript 代码执行的主框架,按照顺序执行,并在每个宏任务执行后检查微任务队列。主要包括:

  • 脚本执行(Script)

    • 加载的 JavaScript 文件或 <script> 标签内的代码块执行。
  • setTimeoutsetInterval

    • 分别用于在指定延迟后或每隔固定时间执行函数。
  • Node.js 中的 setImmediate

    • 安排回调函数在当前 I/O 循环的下一次迭代开始时执行。
  • I/O 操作

    • 包含文件读写、网络请求等,通常以异步方式进行,并通过回调通知完成情况。
  • UI 渲染

    • 浏览器在执行完当前宏任务后,可能会进行界面重绘和样式计算的更新。

8. 什么是执行栈

执行栈,又称调用栈或调用堆栈,是编程语言(尤其是JavaScript)中用于追踪函数调用顺序的核心数据结构。它遵循后进先出(LIFO, Last In First Out)原则,如同一个顶部开口的盒子,最近放入的元素最先被取出。

执行栈的工作原理

1. 函数调用

  • 每当一个函数被激活执行时,其执行上下文(包括局部变量、参数、函数体等信息)会被封装成一个栈帧(Stack Frame),并压入执行栈的顶部。
2. 函数执行
  • 执行栈顶部的函数开始执行。如果此函数内部又调用了其他函数,被调用函数的栈帧会继续被压入栈顶。
3. 函数返回
  • 当一个函数执行完毕,其对应的栈帧会从栈顶弹出,控制权返回到调用它的函数,继续执行剩余代码,直至栈为空。

实际应用中的体现

错误追踪
  • 当JavaScript程序发生异常时,错误堆栈(Error Stack)提供了一条从异常发生点回溯至最初调用的完整路径,极大方便了调试过程。
递归与栈溢出
  • 递归是执行栈的一个典型应用案例,但过度递归可能导致栈空间耗尽,引发栈溢出错误(Stack Overflow)。合理设置递归终止条件或采用迭代等策略是避免此类问题的关键。

理解执行栈的重要性

  • 优化递归逻辑:避免因递归过深引起的栈溢出,通过设计合理的递归终止条件或转换算法逻辑为迭代形式。
  • 高效调试:利用错误堆栈快速识别错误发生的上下文,缩短问题定位时间。
  • 异步编程理解:虽然异步操作并不直接增加执行栈的负担,但其回调函数会在微任务或宏任务队列处理时进入执行栈,深入理解这一机制对于掌握JavaScript的异步编程模型至关重要。
函数内调用
函数执行完毕
所有函数执行完毕
函数调用
创建栈帧并压栈
执行函数
创建新栈帧并压栈
弹出栈帧
返回调用者
执行栈为空

9. Node 中的 Event Loop 和浏览器中的有什么区别

Node.js 中的 Event Loop 和浏览器环境下的 Event Loop 主要区别在于它们的设计目标不同,导致它们的实现细节有所差异,尤其是在事件循环的具体阶段划分上。以下是关键区别和process.nextTick的执行顺序说明:

Node.js 中的 Event Loop 阶段

Node.js 的 Event Loop 包含以下六个阶段,这些阶段按顺序循环执行:

  1. Timers - 处理setTimeout和setInterval的回调。
  2. Pending callbacks - 执行非I/O相关的待处理回调,如setImmediate(在某些旧版本中)。
  3. Idle, Prepare - 内部使用,通常不需要关注。
  4. Poll - 监听新的I/O事件;执行setImmediate(当前版本的主要处理位置)。
  5. Check - 调用setImmediate的回调。
  6. Close callbacks - 如Socket的’close’事件回调。

浏览器中的 Event Loop

相比之下,浏览器的Event Loop主要围绕UI渲染、用户交互和Web API(如setTimeout, fetch, addEventListener等)设计,其模型相对简单,主要关注于执行宏任务(macro tasks)和在每个宏任务结束后立即清空微任务(micro asks)队列。
tprocess.nextTick 特性

  • 独立于Event Loop阶段:process.nextTick在Node.js中是一个特殊的机制,它不直接属于Event Loop的任何一个阶段。每当当前执行的阶段即将结束时,如果有process.nextTick队列,Node.js会清空这个队列中的所有回调,然后执行它们,之后再进入下一个阶段或者处理微任务。
  • 高于微任务的优先级:尽管process.nextTick和Promise的.then回调(微任务)都属于非阻塞操作,但process.nextTick回调会在当前阶段的末尾、微任务之前被执行,这使得它具有更高的优先级 。
  • 连续执行:如果在process.nextTick的回调中又调用了process.nextTick,这些新的回调会累积在同一阶段的末尾执行,而不是分散到不同的循环迭代中。

示例分析
process.nextTick的执行顺序体现了它的高优先级特性:

setTimeout(() => {
  console.log('timer1');
  Promise.resolve().then(function() {
    console.log('promise1');
  });
}, 0);
process.nextTick(() => {
  console.log('nextTick');
  // 连续调用nextTick形成递归,这些递归调用会依次执行
})

输出会是连续的’nextTick’,然后再是’timer1’和’promise1’。这是因为process.nextTick的回调在每个阶段结束时执行,且在微任务(如Promise回调)之前,故会先连续打印所有nextTick的回调内容,之后才是setTimeout和Promise的微任务。

理解这些细微差别对于编写高性能、响应迅速的Node.js应用程序至关重要,尤其是在处理高并发I/O操作和复杂的异步逻辑时。

总之,Node.js与浏览器环境下的Event Loop机制虽有共通之处,但各自的设计目的和应用场景导致它们在具体实现细节上展现出显著差异。Node.js的Event Loop以其独特的六阶段循环,精细化地处理各种异步操作,尤其强调了I/O密集型任务的高效管理。而浏览器的Event Loop则更加侧重于UI渲染和用户交互的即时响应,确保网页的流畅体验。

process.nextTick作为Node.js中的一项特殊机制,凭借其超乎微任务的执行优先级和即时响应能力,为开发者提供了处理高优先级异步逻辑的强有力工具。它不拘泥于Event Loop的特定阶段,而是在每个阶段结束前清空自身的回调队列,确保了高度的灵活性和控制力,但同时也要求开发者审慎使用,以免因过度使用导致的栈溢出或性能瓶颈。

理解这些底层机制对于优化代码执行效率、避免潜在的异步陷阱以及编写更加健壮和可维护的JavaScript应用至关重要。不论是服务端的Node.js环境还是客户端的浏览器环境,深入掌握Event Loop及其相关异步处理模型,都是提升开发者技能树中不可或缺的一环。通过合理安排宏任务与微任务、明智地选用诸如setTimeout、setImmediate、process.nextTick及Promise等工具,可以有效地构建出既高性能又具备良好用户体验的现代Web应用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetCode.96. 不同的二叉搜索树

leetCode.96. 不同的二叉搜索树 题目思路 代码 // 方法一&#xff1a;直接用卡特兰数就行 // 方法二&#xff1a;递归方法 class Solution { public:int numTrees(int n) {// 这里把 i当成整个结点&#xff0c;j当成左子树最左侧结点,并一次当根节点尝试// f[ i ] f[ j - 1…

如何屏幕录制?这3款软件轻松实现!

随着科技的不断发展&#xff0c;屏幕录制成为了人们日常生活中越来越常见的需求。无论是录制游戏过程、分享教程、还是保存重要的在线会议&#xff0c;屏幕录制都是一个非常实用的工具。然而&#xff0c;很多用户却不知道如何屏幕录制。本文将详细介绍3款屏幕录制软件&#xff…

centos 7.9 离线环境安装GPU服务环境

文章目录 centos 7.9 离线环境安装GPU服务环境系统配置更新 gcc更新内核安装显卡驱动安装cuda安装docker 和 nvidia-container-runtime验证 centos 7.9 离线环境安装GPU服务环境 基于centos 7.9 离线安装gpu 服务基础环境&#xff0c;用于在docker 中运行算法服务 系统配置 …

详细分析Oracle修改默认的时间格式(四种方式)

目录 前言1. 会话级别2. 系统级别3. 环境配置4. 函数格式化5. 总结 前言 默认的日期和时间格式由参数NLS_DATE_FORMAT控制 如果需要修改默认的时间格式&#xff0c;可以通过修改会话级别或系统级别的参数来实现 1. 会话级别 在当前会话中设置日期格式&#xff0c;这只会影响…

ThreeJS-3D教学十二:ShaderMaterial

一、首先 Shader 是做什么的 Shader 可以自定义每个顶点、每个片元/像素如何显示&#xff0c;而控制顶点和片元显示是通过设置 vertexShader 顶点着色器和 fragmentShader 片元着色器&#xff0c;这两个着色器用在 ShaderMaterial 和 RawShaderMaterial 材质上。 我们先看一个例…

Web后端开发之前后端交互

http协议 http ● 超文本传输协议 &#xff08;HyperText Transfer Protocol&#xff09;服务器传输超文本到本地浏览器的传送协议 是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程。 HTTP是一个基于TCP/IP通信协议来传递数据. HTT…

HTML5文旅文化旅游网站模板源码

文章目录 1.设计来源文旅宣传1.1 登录界面演示1.2 注册界面演示1.3 首页界面演示1.4 文旅之行界面演示1.5 文旅之行文章内容界面演示1.6 关于我们界面演示1.7 文旅博客界面演示1.8 文旅博客文章内容界面演示1.9 联系我们界面演示 2.效果和源码2.1 动态效果2.2 源代码2.3 源码目…

Oracle、MySQL、PostGreSQL中的多版本读取一致性

multi-version read consistency in Oracle、MySQL、PostGreSQL 在多人同时访问与修改数据时&#xff0c; 最大的难题之一是&#xff1a;一方面要力争最大的并发访问&#xff0c;与此同时还要确保每个用户能以一致的方式读取和修改数据。 ANSI/ISO SQL 标准定义了4 种事务隔离…

“吃饭大学”!中国大学食堂排行TOP10(含西电)

同学们们&#xff0c;考研择校考虑的因素除了学术&#xff0c;地理位置等方面&#xff0c;你们还会考虑哪些因素呢&#xff1f;小研作为一个吃货&#xff0c;必定会考虑的一个因素当然是大学的食堂美食啊~ 那中国超级好吃的大学食堂在哪&#xff1f;一起来看看有没有你的目标院…

input调用手机摄像头实现拍照功能vue

项目需要一个拍照功能&#xff0c;实现功能如下图所示:若使用浏览器则可以直接上传图片&#xff0c;若使用手机则调用手机摄像头拍照。 1.代码结构 <!--input标签--> <input ref"photoRef"type"file"accept"image/*"capture"envir…

4-数据提取方法2(xpath和lxml)(6节课学会爬虫)

4-数据提取方法2&#xff08;xpath和lxml&#xff09;&#xff08;6节课学会爬虫&#xff09; 1&#xff0c;Xpath语法&#xff1a;&#xff08;1&#xff09;选择节点&#xff08;标签&#xff09;&#xff08;2&#xff09;“//”:能从任意节点开始选择&#xff08;3&#xf…

业务链SFC简介

目录 业务链&#xff08;SFC&#xff09;简介什么是业务链&#xff1f;业务链的体系架构业务链的基本工作流程PBRPBR实现的SFC工作流程 NSHNSH报文NSH实现的SFC工作流程 区别 业务链的应用 配置指南 业务链&#xff08;SFC&#xff09;简介 业务链是网络功能虚拟化&#xff08…

华为DCN网络之:VXLAN

VXLAN RFC定义了VLAN扩展方案VXLAN&#xff08;Virtual eXtensible Local Area Network&#xff0c;虚拟扩展局域网&#xff09;。VXLAN采用MAC in UDP封装方式&#xff0c;是NVO3&#xff08;Network Virtualization over Layer 3&#xff09;中的一种网络虚拟化技术。 VXLAN…

【前端】从零开始学习编写HTML

目录 一、什么是前端 二、什么是HTML 三、HTML文件的基本结构 四、HTML常见标签 4.1 注释标签 4.2 标题标签 4.3 段落标签 4.4 换行标签 4.5 格式化标签 4.6 图片标签 4.7 超链接标签 4.8 表格标签 4.9 列表标签 4.10 表单标签 &#xff08;1&#xff09;form标…

介绍两个压测工具pgbench\sysbench,可视化监控工具NMON

性能评估做不好&#xff0c;开会又领导点名叼了。/(ㄒoㄒ)/~~ /(ㄒoㄒ)/~~ /(ㄒoㄒ)/~~ 挨叼了&#xff0c;也要写文章&#xff0c;记录下我的笔记。 写篇文章 对数据库、OS性能的性能评估&#xff0c;需要选择合适的压测工具&#xff0c;给找出数据库的运行瓶颈 pgbench 这是…

Redis 集群模式

一、集群模式概述 Redis 中哨兵模式虽然提高了系统的可用性&#xff0c;但是真正存储数据的还是主节点和从节点&#xff0c;并且每个节点都存储了全量的数据&#xff0c;此时&#xff0c;如果数据量过大&#xff0c;接近或超出了 主节点 / 从节点机器的物理内存&#xff0c;就…

【每日刷题】Day78

【每日刷题】Day78 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1608. 特殊数组的特征值 - 力扣&#xff08;LeetCode&#xff09; 2. 1385. 两个数组间的距离值 - …

实现胶囊神经网络,识别手写MNIST数据集,谈谈实现及理解。

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

在安装HDFS过程中遇见Permission denied

HDFS Shell命令权限不足问题解决 问题 想必有同学在实战Shell的时候&#xff0c;遇到了&#xff1a; Permission denied: userroot, accessWRITE, inode"/":hadoop:supergroup:drwxr-xr-x 这种类似的问题。 问题的原因就是没有权限&#xff0c;那么为什么呢&#…

C# OpenCvSharp 实现Reinhard颜色迁移算法

C# OpenCvSharp 实现Reinhard颜色迁移算法 目录 效果 项目 代码 下载 效果 项目 Reinhard颜色迁移算法的步骤&#xff1a; 1、将参考图片和目标图片转换到LAB空间下 2、得到参考图片和目标图片的均值和标准差 3、对目标图片的每一个像素值&#xff0c;减去目标图像均值然后…