JavaScript中的Event事件对象详解

news2025/4/20 7:35:12

一、事件对象(Event)概述

1. 事件对象的定义

event 对象是浏览器自动生成的对象,当用户与页面进行交互时(如点击、键盘输入、鼠标移动等),事件触发时就会自动传递给事件处理函数event 对象包含了与事件相关的各种信息,开发者可以通过访问 event 对象的属性来获取具体的事件细节,并执行相应的操作。

2. 事件的类型

在 JavaScript 中,事件类型非常丰富,常见的包括:

  • 鼠标事件:click(点击)、dblclick(双击)、mousedown(按下鼠标)、mouseup(释放鼠标)、mousemove(移动鼠标)、mouseenter(鼠标进入元素)、mouseleave(鼠标离开元素)等。
  • 键盘事件:keydown(按下键盘)、keypress(按下字符键)、keyup(释放键盘)。
  • 表单事件:submit(提交表单)、focus(聚焦)、blur(失焦)。
  • 触摸事件:touchstart(触摸开始)、touchmove(触摸移动)、touchend(触摸结束)。
  • 窗口事件:resize(窗口大小变化)、scroll(滚动)。


通过绑定不同类型的事件,开发者可以实现丰富的交互效果。

注:其实事件一直都是存在的(不管有没有绑定 或 监听),它只是没有事件处理程序而已!!!

JavaScript事件是在浏览器文档(document)窗口中的发生的特定的交互瞬间;而JavaScript和HTML之间的交互行为就是通过事件来触发的。

事件处理程序:

事件处理程序:我们用户在页面中进行的点击这个动作,鼠标移动的动作,网页页面加载完成的动作等,都可以称之为事件名称,

即:click、mousemove、load等都是事件的名称。响应某个事件的函数则称为事件处理程序,或者叫做事件侦听器。

二、Event 对象的常见属性

1. type 属性

type 属性返回触发事件的类型,以字符串形式表示。例如,鼠标点击触发的事件类型为 "click",键盘按下触发的事件类型为 "keydown"。这是判断事件类型的重要依据。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件类型打印</title>
</head>

<body>
    <button id="clickBtn">点击按钮</button>
    <input type="text" id="inputBox" placeholder="输入内容">
    <script>
        const clickBtn = document.getElementById('clickBtn');
        const inputBox = document.getElementById('inputBox');

        clickBtn.addEventListener('click', (event) => {
            console.log(`你触发了 ${event.type} 事件`);
        });

        inputBox.addEventListener('input', (event) => {
            console.log(`你触发了 ${event.type} 事件,当前输入内容为:${inputBox.value}`);
        });

        document.addEventListener('keydown', (event) => {
            console.log(`检测到 ${event.type} 事件,你按下了 ${event.key} 键`);
        });
    </script>
</body>

</html>

2.target:找到事件真正的源头​

作用:指向用户实际操作的那个元素(哪怕事件是从父元素冒泡上来的)

案例:点击列表项显示被点击的内容

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件类型打印</title>
</head>

<body>
    <ul id="list">
        <li>苹果</li>
        <li>香蕉</li>
        <li>橙子</li>
    </ul>
    <script>
        list.addEventListener('click', (event) => {
            // 无论点击哪个<li>,都会显示对应的水果名称
            console.log(`你点击了:${event.target.textContent}`);
        });

        document.addEventListener('click', (event) => {
            console.log(event.target); // 输出被点击的元素
        });

    </script>
</body>

</html>

3.currentTarget 属性

currentTarget  target 不同,它表示当前事件监听器所绑定的元素。即使事件是从子元素触发的,currentTarget 始终指向绑定事件处理函数的元素。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>currentTarget与target对比</title>
    <style>
        .parent {
            border: 2px solid blue;
            padding: 10px;
        }

        .child {
            border: 2px solid green;
            padding: 10px;
        }

        .grand-child {
            border: 2px solid red;
            padding: 10px;
        }
    </style>
</head>

<body>
    <div class="parent" id="parent">
        父元素
        <div class="child" id="child">
            子元素
            <button class="grand-child" id="btn">孙元素按钮</button>
        </div>
    </div>
    <script>
        const parent = document.getElementById('parent');
        parent.addEventListener('click', (event) => {
            console.log("currentTarget:", event.currentTarget);
            console.log("target:", event.target);
        });
    </script>
</body>

</html>

4.key:获取键盘按下的字符(推荐使用)​

作用:返回按下的具体按键(字母、数字、功能键等),替代已废弃的keyCode

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>key 属性示例</title>
</head>

<body>
    <input type="text" id="inputField">
    <script>
        const inputField = document.getElementById('inputField');
        inputField.addEventListener('keydown', (event) => {
            console.log(`你按下了:${event.key}`);
        });
    </script>
</body>

</html>

5.altKey/ctrlKey/shiftKey:检测修饰键是否按下

作用:判断是否同时按下了 Alt/Ctrl/Shift 键(返回 true/false)
案例:检测 Ctrl+S 组合键,在控制台打印提示

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>修饰键检测</title>
</head>

<body>
    <script>
        document.addEventListener('keydown', (event) => {
            if (event.ctrlKey && event.key === 's') {
                event.preventDefault(); // 阻止默认保存行为
                console.log('Ctrl + S 组合键被按下');
            }
        });

    </script>
</body>

</html>

6.button:判断按下的鼠标按钮

作用:在鼠标点击事件中,区分左 / 中 / 右键(0 = 左键,1 = 中键,2 = 右键)
案例:点击鼠标,在控制台打印按下的按钮信息

三、事件对象的核心方法

1.阻止默认行为:preventDefault()

用于取消事件的默认动作,如阻止表单提交或链接跳转:

document.querySelector('a').addEventListener('click', (event) => {
  event.preventDefault(); // 阻止链接跳转
  console.log('链接被点击,但未跳转');
});

2 阻止事件冒泡:stopPropagation()

防止事件在DOM层级中继续向上传播:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>stopPropagation示例</title>
    <style>
        #container {
            width: 200px;
            height: 200px;
            background-color: lightblue;
            padding: 10px;
        }

        #child {
            width: 100px;
            height: 100px;
            background-color: lightcoral;
        }
    </style>
</head>

<body>
    <div id="container">
        父容器
        <div id="child">子元素</div>
    </div>
    <script>
        const container = document.getElementById('container');
        const child = document.getElementById('child');

        container.addEventListener('click', (event) => {
            console.log('容器被点击');
        });

        child.addEventListener('click', (event) => {
            event.stopPropagation(); // 阻止事件冒泡到父容器
            console.log('子元素被点击,但不会触发父元素事件');
        });
    </script>
</body>

</html>

⑴把 event.stopPropagation();注释掉

3.立即停止事件流:stopImmediatePropagation()

同时阻止冒泡和同一元素上其他监听器的执行:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>stopImmediatePropagation示例</title>
    <style>
        button {
            padding: 10px 20px;
            font-size: 16px;
        }
    </style>
</head>

<body>
    <button id="button">点击按钮</button>
    <script>
        document.getElementById('button').addEventListener('click', (event) => {
            console.log('第一个监听器');
            event.stopImmediatePropagation();
        });

        document.getElementById('button').addEventListener('click', (event) => {
            console.log('第二个监听器(不会执行)');
        });
    </script>
</body>

</html>

四、事件流:

浏览器层次顺序:document -> html -> body -> div父元素 -> input子元素】,document最上层祖先元素, input最下层后代元素。

1.🍀什么是事件流:

事件流是描述从页面中接收事件的顺序【从内到外(冒泡),从外到内(捕获)】;
IE与原来的NetScape(网景),对于事件流提出的是完全不同的顺序。IE团队提出的是事件冒泡流;NetScape的事件流是事件捕获流。
    简单的讲:当给一个DIV绑定一个点击事件,又在DIV里面放一个按扭并给按扭也绑定一个点击事件,此时你点击里面按扭的同时,外面DIV的点击事件也会被触发。
 


2.🍀事件冒泡:

所谓事件冒泡 就是事件最开始从最具体的元素(文档中嵌套层次最深的那个点【当前绑定事件的那个元素】)接收,然后逐级向上传播至最不具体的那个节点(document节点,即最上层的节点)。
阻止事件冒泡方法:event.stopPropagation()

阻止默认行为方法:event.preventDefault() 

注意:这两个方法属于event对象中的。


3.🍀事件捕获:

事件捕获和事件冒泡刚好【相反】,它是事件从最不具体的节点(document)先接收到事件,然后再向下逐一捕获至(文档中嵌套层次最深的那个点【当前绑定事件的那个元素】)。
    简单地说,事件冒泡和事件捕获都是一种事件传递的机制。这种机制可以使事件在不同级
的元素间传递。事件冒泡是从事件触发的源节点,向父节点传递,直到到达最顶节点。而事件
捕获则是从最顶节点,逐步向下传递,直到到达事件触发的源节点。

    在一些标准的浏览器中,如IE9以上,Chrome 、Firefox 、Safari浏览器等,支持这两种冒泡方式。而事实上,
准确的说,是这两种方式的混合方式。因为W3C采取的就是这两种方式的结合:先从顶级节点
开始,将事件向下传递至源节点,再从源节点冒泡至顶节点。

    而在IE及Opera(以下说的都是老版本的欧朋,新版本的欧朋经检测是支持事件捕获的)
下,是不支持事件捕获的。而这个特点最明显体现在事件绑定函数上。IE、Opera的事件
绑定函数是attachEvent,而Chrome等浏览器则是addEventListener,

    而后者比前者的参数多了一个——这个参数是一个布尔值,这个布尔值由用户决定,用户若设为true,则该绑定事件以事件捕获的形式参与,若为false则以事件冒泡的形势参与。

而这个参数在IE和Opera浏览器中是不存在的——根本原因是它们不支持事件捕获。

五、📚事件绑定:

1.🍀事件绑定方式1:

HTML事件内嵌绑定,就是将事件直接内嵌内HTML结构标签元素内的【不推荐用,因为不灵活】 
 

<input type="button" onclick="alert("我是事件绑定方式一:HTML事件处理程序,我是内嵌在HTML结构中的");" value="事件绑定方式一【内嵌】" />
<input type="button" onclick="mupiaoFn()" value="事件绑定方式一【调用】" />

HTML事件处理程序:

function mupiaoFn() {
    alert("我是事件绑定方式1:HTML事件处理程序");
};


2.🍀事件绑定方式2:

【DOM 0级事件处理程序】就是把一个函数/方法赋给一个事件处理程的 属性如:id 、class 、元素名等 【用得最多,兼容性好,简单,灵活,跨浏览器 ;缺点:不能绑定多个同类型事件】
 

<input type="button" name="eventBtn2" id="eventBtn2" value="事件绑定方式二【通用属性绑定】" />

DOM 0级事件处理程序

var Btn2 = document.getElementById("eventBtn2");//给谁绑定事件,就要先获取谁

绑定事件1:【赋给方式】

Btn2.onclick = function() {
    alert("我是事件绑定方式二:DOM 0级事件处理程序");
};

绑定事件2:【调用方式】

function publick() {
    alert("我也是事件绑定方式二:DOM 0级事件处理程序");
};
 
Btn2.onclick = publick; //注:publick后面不要加()括号,否则会变为立即执行函数!

删除事件:

Btn2.onclick = null; 


注意事项:

  1. 在DOM0级事件处理程序推出之后,被广为使用,可是出现了这样一个问题,当我们希望给同一个元素/标签绑定多个同类型事件的时候(如,为上面的按扭标签绑定2个或是个以上的点击事件),是不被允许的。
  2. 那么,此时,出现了另一种事件处理程序,就是DOM2级的事件处理程序,【注:没有DOM1级事件这个概念哦】在DOM2级当中,定义了两个基本方法,
  3. 用于处理指定(即绑定)和删除事件处理程序的操作,分别是addEventListener()和removeEventListener(),IE9+、FireFox、Safari、Chrome和Opera都是支持DOM2级事件处理程序的。
  4. 对于IE8-,则使用的是IE专有的事件处理程序:两个类似的方法——attachEvent()与detachEvent()。


3.🍀事件绑定方式3:

【DOM 2级事件处理程序 事件委托】:

除了以上两种事件绑定方式都需要一个一个的绑定和添加事件,还有一种(事件委托)把事件处理程序挂载在父节点上,利用事件冒泡机制在父节点统一处理事件,这样就不用一个一个的绑定和添加事件了。

addEventListener()和removeEventListener()监听事件接收3个参数:

  1. 事件类型(注:不要加 on)
  2. 事件函数(事件处理程序)
  3. 是否捕获 false:冒泡,true:捕获

注:在IE浏览器中用 attachEvent()和detachEvent()监听事件接收2个参数:事件类型(注:要加 on), 处理函数/只支持冒泡

例:

<ul id="list">
    <li class="item">Item 1</li>
    <li class="item">Item 2</li>
    <li class="item">Item 3</li>
    ...
</ul>

DOM 2级事件处理程序 / 监听事件

var list= document.getElementById("list");//给谁绑定事件,就要先获取谁

添加监听事件1:【内嵌方式】

list.addEventListener('click' , function(event) {
 
    alert("我是事件绑定方式二:DOM 2级事件处理程序");
    
    // const li = event.target;
    const li = event.target.closest('li'); // closest()方法返回最近的祖先元素
 
    if (item.style.backgroundColor) {
         li.style.backgroundColor = 'red'
    } else {
        li.style.backgroundColor = 'blue';
 
    }
 
} , false); //false:冒泡,true:捕获


添加监听事件2:【调用方式】

list.addEventListener('click' , addevFn , false);
 
function addevFn(event) {
    alert("我是事件绑定方式二:DOM 2级事件处理程序 【调用方式】");
    
    // const li = event.target;
    const li = event.target.closest('li');
 
    if (item.style.backgroundColor) {
         li.style.backgroundColor = 'red'
    } else {
        li.style.backgroundColor = 'blue';
 
    }
};


IE8及以下的添加和删除监听事件方法:(注:IE9及以上的就用上面的方法啦)

IE8及以下的添加监听事件1:【内嵌方式】 (注 attachEvent 和 detachEvent方法只传两个参数,前面两个和上面一样,而第3个参数是因为在IE中默认就是冒泡方式,所以不用传第3个参数啦)

list.attachEvent("onclick" , function(event) {
 
    alert("我是IE8及以下的添加监听事件方法,【内嵌方式】");
});


IE8及以下的添加监听事件2:【调用方式】(注:attachEvent 和 detachEvent 事件类型前而一定要加  on 才可以哦)

list.attachEvent("onclick" , addevFn3);
 
function addevFn3(event) {
 
    alert("我是IE8及以下的添加监听事件方法,【调用方式】");
};


IE8及以下的删除监听事件

Btn3.detachEvent("onclick" , addevFn3);


🍀事件方面性能优化:

    在JavaScript代码当中,添加到页面中的事件越多,页面的性能也就越差。导致这一问题的原因主要有:

  • 每个函数都是对象,都会占用内存。内存中对象越多,性能也就越差。
  • 必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。
  • 为了进行页面的性能优化,因此我们会采用两种方法,就是上面提到的——事件委托和事件处理程序的移除。

事件委托的好处:

  • 在大量子元素需要绑定事件处理程序的情况下,事件委托可明显减少内存消耗
  • 事件委托实现了动态绑定,后续新增的子节点不需要额外去绑定事件处理程序

事件委托的缺点:

  • 事件委托必需要能支持冒泡的事件类型,有些事件是不支持冒泡的 如(1、focus事件;2、blur事件;3、scroll事件;4、mouseenter和mouseleave事;5、mouseover和mouseout事件;6、mousemove事件;7、keypress事件;8、beforeunload事件;9、domcontentloaded事件;10、cut、copy和paste事件等)
  • 需要确保事件对象(event.target)是对应要处理的元素的!

📚事件委托: 

关于什么时候使用事件委托,其实,简单来说,当时一个页面事件处理程序比较多的时候,我们通常情况下会使用它。

    事件委托主要利用了事件冒泡,只指定一个事件处理程序,就可以管理一个类型的所有事件。例如:我们为整个一个页面制定一个onclick事件处理程序,
此时我们不必为页面中每个可点击的元素单独设置事件处理程序

    事件委托:给元素的父级或者祖级,甚至页面绑定事件,然后利用事件冒泡的基本原理,通过事件目标对象进行检测,然后执行相关操作。其优势在于:

    大大减少了事件处理程序的数量,在页面中设置事件处理程序的时间就更少了(DOM引用减少——也就是上面我们通过id去获取标签,所需要的查找操作以及DOM引用也就更少了)。
    document(注:上面的例子没有绑定在document上,而是绑定到了父级的div上,最为推荐的是绑定在document上)对象可以很快的访问到,而且可以在页面生命周期的任何时点上为它添加事件处理程序,并不需要等待DOMContentLoaded或者load事件。换句话说,只要可单击的元素在页面中呈现出来了,那么它就立刻具备了相应的功能。
整个页面占用的内存空间会更少,从而提升了整体的性能。
 

📚移除事件处理程序 
 
    每当将一个事件处理程序指定给一个元素时,在运行中的浏览器代码与支持页面交互的JavaScript代码之间就会建立一个连接。连接数量也直接影响着页面的执行速度。
所以,当内存中存在着过时的“空事件处理程序”的时候,就会造成Web应用程序的内存和性能问题。

那么什么时候会造成“空事件处理程序”的出现呢?

    文档中元素存在事件,通过一些DOM节点操作(removeChild、replaceChild等方法),移除了这个元素,但是DOM节点的事件没有被移除。
innerHTML去替换页面中的某一部分,页面中原来的部分存在事件,没有移除。
页面卸载引起的事件处理程序在内存中的滞留。

🍀解决方法:

  1. 合理利用事件委托;
  2. 在执行相关操作的时候,先移除掉事件,再移除DOM节点;
  3. 在页面卸载之前,先通过onunload事件移除掉所有事件处理程序。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

王牌学院,25西电通信工程学院(考研录取情况)

1、通信工程学院各个方向 2、通信工程学院近三年复试分数线对比 学长、学姐分析 由表可看出&#xff1a; 1、信息与通信工程25年相较于24年上升5分、军队指挥学25年相较于24年上升30分 2、新一代电子信息技术&#xff08;专硕&#xff09;25年相较于24年下降25分、通信工程&…

深入理解 Java 多线程:锁策略与线程安全

文章目录 一、常见的锁策略1. 乐观锁&&悲观锁2. 读写锁3. 重量级锁&&轻量级锁4. 自旋锁5. 公平锁&&不公平锁6. 可重入锁 && 不可重入锁 二、CAS1. 什么是 CAS2. CAS 是怎么实现的3.CAS 有哪些应用1) 实现原子类2) 实现自旋锁 4. CAS 的 ABA 问…

Java数据结构——ArrayList

Java中ArrayList 一 ArrayList的简介二 ArrayList的构造方法三 ArrayList常用方法1.add()方法2.remove()方法3.get()和set()方法4.index()方法5.subList截取方法 四 ArrayList的遍历for循环遍历增强for循环(for each)迭代器遍历 ArrayList问题及其思考 前言 ArrayList是一种 顺…

科学量化AI对品牌产品印象 首个AI印象(AII)指数发布

2025年4月18日&#xff0c;营销传播数据研究领先机构四度传播研究院(SAC)&#xff0c;正式推出了量化AI大模型对产品整体印象的AI印象&#xff0c;简称AII&#xff08;ARTIFICIAL INTELLIGENCE IMPRESSIONS&#xff09;&#xff0c;同时发布了首个“汽车AI印象榜”。为企业和消…

FFmpeg 硬核指南:从底层架构到播放器全链路开发实战 基础

目录 1.ffmpeg的基本组成2.播放器的API2.1 复用器阶段2.1.1 分配解复用上下文2.1.2 文件信息操作2.1.3 综合示例 2. 2 编解码部分2.2.1 分配解码器上下文2.2.2编解码操作2.2.3 综合示例 3 ffmpeg 内存模型3.1 基本概念3.2API 1.ffmpeg的基本组成 模块名称功能描述主要用途AVFo…

UE5有些场景的导航生成失败解决方法

如果导航丢失&#xff0c;就在项目设置下将&#xff1a; 即可解决问题&#xff1a; 看了半个小时的导航生成代码发现&#xff0c;NavDataSet这个数组为空&#xff0c;导致异步构建导航失败。 解决 NavDataSet 空 无法生成如下&#xff1a; 当 NavDataSet 为空的化 如果 bAut…

MCP(Model Context Protocol 模型上下文协议)科普

MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是由人工智能公司 Anthropic 于 2024年11月 推出的开放标准协议&#xff0c;旨在为大型语言模型&#xff08;LLM&#xff09;与外部数据源、工具及服务提供标准化连接&#xff0c;从而提升AI在实际…

健康养生指南

在快节奏的现代生活中&#xff0c;健康养生成为人们关注的焦点。它不仅关乎身体的强健&#xff0c;更是提升生活质量、预防疾病的关键。掌握科学的养生方法&#xff0c;能让我们在岁月流转中始终保持活力。 饮食是健康养生的基础。遵循 “均衡膳食” 原则&#xff0c;每日饮食需…

Linux系统:进程终止的概念与相关接口函数(_exit,exit,atexit)

本节目标 理解进程终止的概念理解退出状态码的概念以及使用方法掌握_exit与exit函数的用法以及区别atexit函数注册终止时执行的函数相关宏 一、进程终止 进程终止&#xff08;Process Termination&#xff09;是指操作系统结束一个进程的执行&#xff0c;回收其占用的资源&a…

Linux下 文件的查找、复制、移动和解压缩

1、在/var/log目录下创建一个hehe.log的文件&#xff0c;其文件内容是&#xff1a; myhostname ghl mydomain localdomain relayhost [smtp.qq.com]:587 smtp_use_tls yes smtp_sasl_auth_enable yes smtp_sasl_security_options noanonymous smtp_sasl_tls_security_opt…

C语言学习之预处理指令

目录 预定义符号 #define的应用 #define定义常量 #define定义宏 带有副作用的宏参数 宏替换的规则 函数和宏定义的区别 #和## #运算符 ##运算符 命名约定 #undef ​编辑 命令行定义 条件编译 头文件包含 头文件被包含的方式 1.本地头文件包含 2.库文件包含 …

【STM32单片机】#10 USART串口通信

主要参考学习资料&#xff1a; B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接&#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装&#xff1a;STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 实验&…

fastlio用mid360录制的bag包离线建图,提示消息类型错误

我用mid360录制的bag包&#xff0c;激光雷达的数据类型是sensor_msgs::PointCloud2&#xff0c;但是运行fast_lio中的mid360 launch文件&#xff0c;会报错&#xff08;没截图&#xff09;&#xff0c;显示无法从livox_ros_driver2::CustomMsg转换到sensor_msgs::PointCloud2。…

二级评论列表-Java实现

二级评论列表是很常见的功能&#xff0c;文章记录了新手用Java实现的具体逻辑。 整体实现逻辑是先用2个sql&#xff0c;分别查出两层数据。然后用java在service中实现数据组装&#xff0c;返给前端。这种实现思路好处是SQL简洁&#xff0c;逻辑分明&#xff0c;便于维护。 一…

IP检测工具“ipjiance”

目录 IP质量检测 应用场景 对网络安全的贡献 对网络管理的帮助 对用户决策的辅助作用 IP质量检测 检测IP的网络提供商&#xff1a;通过ASN&#xff08;自治系统编号&#xff09;识别IP地址所属的网络运营商&#xff0c;例如电信、移动、联通等。 识别网络类型&#xff1…

Replicate Python client

本文翻译整理自&#xff1a;https://github.com/replicate/replicate-python 文章目录 一、关于 Replicate Python 客户端相关链接资源关键功能特性 二、1.0.0 版本的重大变更三、安装与配置1、系统要求2、安装3、认证配置 四、核心功能1、运行模型2、异步IO支持3、流式输出模型…

deekseak 本地windows 10 部署步骤

有些场景需要本地部署&#xff0c;例如金融、医疗&#xff08;HIPAA&#xff09;、政府&#xff08;GDPR&#xff09;、军工等&#xff0c;需完全控制数据存储和访问权限&#xff0c;避免云端合规风险或者偏远地区、船舶、矿井等无法依赖云服务&#xff0c;关键设施&#xff08…

<sql>、<resultMap>、<where>、<foreach>、<trim>、<set>等标签的作用和用法

目录 一. sql 代码片段标签 二. resultMap 映射结果集标签 三. where 条件标签 四. set 修改标签 五. trim 标签 六. foreach 循环标签 一. sql 代码片段标签 sql 标签是 mybatis 框架中一个非常常用的标签页&#xff0c;特别是当一张表很有多个字段多&#xff0c;或者要…

【项目】CherrySudio配置MCP服务器

CherrySudio配置MCP服务器 &#xff08;一&#xff09;Cherry Studio介绍&#xff08;二&#xff09;MCP服务环境搭建&#xff08;1&#xff09;环境准备&#xff08;2&#xff09;依赖组件安装<1> Bun和UV安装 &#xff08;3&#xff09;MCP服务器使用<1> 搜索MCP…

【技术派后端篇】 Redis 实现用户活跃度排行榜

在各类互联网应用中&#xff0c;排行榜是一个常见的功能需求&#xff0c;它能够直观地展示用户的表现或贡献情况&#xff0c;提升用户的参与感和竞争意识。在技术派项目中&#xff0c;也引入了用户活跃度排行榜&#xff0c;该排行榜主要基于 Redis 的 ZSET 数据结构来实现。接下…