js 之 事件处理

1、html事件
<button id="btn" onclick="clickHandle()">按钮</button>

    <script>
        function clickHandle(){
            console.log("html事件");
            
        }
    </script>
缺点:html和js代码混合,没有分离


2、DOM0级事件
<button id="btn">按钮</button>

    <script>
        var btn = document.getElementById("btn")

        //被下面的事件覆盖了
        btn.onclick = function clickHandle(){
            console.log("dom0事件1");    
        }

        btn.onclick = function clickHandle(){
            console.log("dom0事件2");    
        }

        
    </script>

优点:html和js代码分离了,
缺点:但是无法同时添加多个点击事件


3、DOM2级事件
<button id="btn">按钮</button>

    <script>
        var btn = document.getElementById("btn")

        btn.addEventListener("click", function(){
            console.log("dom2事件1"); 
        })

        btn.addEventListener("click", function(){
            console.log("dom2事件2"); 
        })
        
    </script>
优点:既可以实现代码分离,也可以添加多个点击事件



addEventlistener 介绍:
1、基本介绍
addEventListener 是绑定事件处理程序的标准方法,用于给 DOM 元素、window、document 等对象添加事件监听(如点击、输入、加载等)

核心语法:
目标对象.addEventListener(事件类型, 处理函数, [选项/冒泡/捕获]);  // []表示可选

        目标对象:要绑定事件的元素(如 document、window、button 等 DOM 节点);
        事件类型:字符串,如 'click'(点击)、'input'(输入)、'load'(加载),不带 on 前缀(区别于 onclick);
        处理函数:事件触发时执行的函数(可传匿名函数、命名函数);
        可选参数:控制事件的冒泡 / 捕获或自动移除(通常传布尔值或对象)

eg:
// 获取按钮元素
const btn = document.querySelector('button');

// 绑定点击事件(匿名函数)
btn.addEventListener('click', function(e) {
  console.log('按钮被点击了');
  console.log('事件对象:', e); // e 是事件对象,包含事件相关信息
});

// 绑定点击事件(命名函数,便于后续移除)
function handleClick(e) {
  console.log('点击事件(命名函数)');
}
btn.addEventListener('click', handleClick);


2、事件对象(e)的常用属性 / 方法
事件处理函数的参数 e(通常叫 event)是事件对象,包含事件的关键信息:
btn.addEventListener('click', function(e) {
  // 1. 触发事件的元素(当前元素)
  console.log('当前元素:', e.target); 
  // 2. 绑定事件的元素(可能和 target 不同,比如事件冒泡时)
  console.log('绑定事件的元素:', e.currentTarget); 
  // 3. 阻止默认行为(如阻止表单提交、链接跳转)
  e.preventDefault(); 
  // 4. 阻止事件冒泡/捕获
  e.stopPropagation(); 
  // 5. 事件类型(如 'click')
  console.log('事件类型:', e.type); 
});


3、可选参数介绍:控制事件流(冒泡 / 捕获)
DOM 事件会经历捕获阶段 → 目标阶段 → 冒泡阶段,addEventListener 的第三个参数控制监听的阶段:
    传 false(默认):在冒泡阶段触发处理函数;
    传 true:在捕获阶段触发处理函数;
    传对象(如 { capture: true, once: true }):更灵活的配置(常用 once: true 表示事件只触发一次)。



# 常见的事件类型
1、鼠标事件
鼠标事件主要指与鼠标相关的事件,具体的事件主要有以下一些
click:单击鼠标时触发
dblclick:在同一个元素上双击鼠标时触发
mousedown:按下鼠标键时触发
mouseup:释放按下的鼠标键时触发
mousemove:当鼠标在节点内部移动时触发。当鼠标持续移动时,该事件会连触发。
mouseenter:鼠标进入一个节点时触发,进入子节点不会触发这个事件
mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件
mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件◎ mouseout:鼠标离开一个节点时触发,离开父节点也会触发这个事件
 wheel:滚动鼠标的滚轮时触发

eg:
<button id="btn">按钮</button>

    <script>
        var btn = document.getElementById("btn")

        btn.ondblclick = function dbclickHandle(){
            console.log("鼠标双击事件");
            
        }

    </script>


2、键盘事件
键盘事件由用户击打键盘触发,主要有keydown、keypress、keyup三个事件
keydown:按下键盘时触发。
keypress:按下有值的键时触发,即按下 Ctr1、Alt、Shift、Meta 这样无值的键,这个事件不会触发。
对于有值的键,按下时先触发keydown事件,再触发这个事件。
keyup:松开键盘时触发该事件


3、表单事件
表单事件是在使用表单元素及输入框元素可以监听的一系列事件
input事件
select事件
Change事件
reset事件
submit事件
-------------------------------------------------------------------------------------------

补充个知识点:
DOM 事件会经历捕获阶段 → 目标阶段 → 冒泡阶段   三个阶段啥意思
<!--

DOM 事件的「捕获阶段 → 目标阶段 → 冒泡阶段」是事件在 DOM 树中传播的完整流程,
核心是:当一个元素触发事件(比如点击按钮),事件不会只停在这个元素上,
而是会先从最外层的根节点向下 “捕获” 到目标元素,再从目标元素向上 “冒泡” 回根节点。

eg:
用一个直观的 DOM 结构举例(嵌套的三层元素):
 DOM 树结构:html → body → parent → child(按钮) -
<div class="parent" style="padding: 20px; background: #eee;">
  父元素
  <button class="child">子按钮</button>
</div>
当点击「子按钮」时,事件会按以下三个阶段传播:

1、捕获阶段(Capture Phase):从 “根” 到 “目标”,自上而下
事件首先从 DOM 树的最顶层节点(window → document → html → body)开始,
向下遍历到触发事件的目标元素(子按钮),这个过程就是 “捕获”。
作用:允许外层元素在事件到达目标前 “拦截” 事件;
只有通过 addEventListener 第三个参数设为 true(或 {capture: true})的监听函数,才会在这个阶段触发。
示例:
const parent = document.querySelector('.parent');
const child = document.querySelector('.child');

// 父元素在捕获阶段监听点击
parent.addEventListener('click', () => {
  console.log('父元素 - 捕获阶段');
}, true); // 第三个参数true → 捕获阶段触发

// 子按钮(目标)在捕获阶段监听
child.addEventListener('click', () => {
  console.log('子按钮 - 捕获阶段');
}, true);
点击子按钮时,先输出「父元素 - 捕获阶段」,再输出「子按钮 - 捕获阶段」(自上而下)。
注意:有多层父元素时,如果想多层父元素都拦截,那每个父元素都要监听点击,即每个父元素都要写个
父元素标签名.addEventListener()监听事件

2、目标阶段(Target Phase):事件到达真正触发的元素
当事件传播到实际触发事件的目标元素(比如点击的子按钮),进入 “目标阶段”。
此时,无论监听函数是设置为 “捕获”(true)还是 “冒泡”(false),都会触发(优先级无差别,按绑定顺序执行);
这是事件传播的核心阶段,也是我们最常处理事件的阶段。


3、冒泡阶段(Bubbling Phase):从 “目标” 到 “根”,自下而上
事件到达目标元素后,会向上回溯(子按钮 → 父元素 → body → html → document → window),这个过程就是 “冒泡”。
作用:允许内层元素的事件 “传递” 给外层元素,实现 “事件委托”;
addEventListener 第三个参数默认是 false,监听函数默认在这个阶段触发;
可以用 e.stopPropagation() 阻止冒泡(事件不再向上传播)。
示例:
// 父元素在冒泡阶段监听(默认)
parent.addEventListener('click', () => {
  console.log('父元素 - 冒泡阶段');
}, false); // 第三个参数false(默认)→ 冒泡阶段触发

// 子按钮在冒泡阶段监听
child.addEventListener('click', (e) => {
  console.log('子按钮 - 冒泡阶段');
  // e.stopPropagation(); // 取消这行注释,父元素的冒泡事件不会触发
});
点击子按钮时,先输出「子按钮 - 冒泡阶段」,再输出「父元素 - 冒泡阶段」(自下而上);
若打开 e.stopPropagation(),父元素的冒泡事件会被阻止。



核心应用场景
1、事件委托(冒泡的核心价值)
不需要给每个子元素绑定事件,只需给父元素绑定,利用冒泡特性处理所有子元素的事件(减少内存占用):
javascript
运行
// 父元素监听所有子按钮的点击(冒泡阶段)
parent.addEventListener('click', (e) => {
  if (e.target.classList.contains('child')) {
    console.log('子按钮被点击(事件委托)');
  }
});
2、拦截事件(捕获阶段)
比如在 document 捕获阶段拦截所有点击,实现全局事件控制:
javascript
运行
document.addEventListener('click', (e) => {
  console.log('全局拦截点击(捕获阶段)');
}, true);
3、阻止冒泡 / 捕获
e.stopPropagation():阻止事件继续传播(捕获 / 冒泡都停);
e.stopImmediatePropagation():不仅阻止传播,还阻止当前元素的其他监听函数执行。

posted @ 2025-12-11 14:40  有形无形  阅读(12)  评论(0)    收藏  举报