JavaScript常用DOM API研究详解03_事件监听器_addEventListener_removeEventListener_常见事件及应用

JavaScript常用DOM API研究详解03:事件监听器、addEventListener、removeEventListener、常见事件及应用

在现代Web开发中,事件是用户与网页交互的核心机制。JavaScript通过事件机制,允许开发者对用户的操作做出响应,如点击按钮、输入文本、移动鼠标等。**事件监听器(Event Listener)**是处理这些事件的关键工具。

本文将深入探讨JavaScript中事件监听器的使用,包括:

  • 事件监听器的基本概念
  • addEventListener() 方法的详细介绍
  • removeEventListener() 方法的使用
  • 常见事件类型及其应用
  • 实践示例

一、事件监听器的基本概念

1. 什么是事件?

事件是用户或浏览器执行的某种动作,可以被JavaScript捕获并作出响应。常见的事件类型包括:

  • 鼠标事件clickdblclickmouseovermouseoutmousemove
  • 键盘事件keydownkeypresskeyup
  • 表单事件submitresetfocusblurchange
  • 窗口事件loadresizescrollunload

2. 什么是事件监听器?

事件监听器(也称为事件处理程序)是一个函数,当特定事件发生在某个元素上时,浏览器会调用该函数。通过添加事件监听器,我们可以在用户与网页交互时执行特定的代码。


二、addEventListener() 方法

1. 方法简介

addEventListener() 方法用于向指定元素添加事件监听器,当指定的事件发生时,调用关联的处理函数。

2. 语法

target.addEventListener(type, listener[, options]);
  • target:要添加事件监听器的目标对象,可以是任何支持事件的对象(如DOM元素、windowdocument 等)。
  • type:字符串,表示要监听的事件类型,不含on前缀(如'click''keydown')。
  • listener:当事件触发时被调用的函数(事件处理程序)。
  • options(可选):一个对象,指定事件监听器的属性。

3. 参数详解

3.1 type

事件类型的字符串,不含on前缀。例如:

  • 'click':鼠标点击事件
  • 'mouseover':鼠标移入事件
  • 'keydown':按下键盘按键事件
3.2 listener

一个函数,当事件触发时被调用。函数的第一个参数是事件对象 event,包含了事件的相关信息。

示例:

function handleClick(event) {
  console.log('元素被点击了');
}
3.3 options

可选参数,用于指定事件监听器的属性,可以是一个布尔值或一个对象。

  • capture:布尔值,是否在捕获阶段触发事件处理程序。默认值为false(冒泡阶段)。
  • once:布尔值,是否只触发一次。为true时,事件处理程序在触发后会被自动移除。
  • passive:布尔值,表示事件处理程序永远不会调用 preventDefault(),提高性能。

示例:

element.addEventListener('click', handleClick, { once: true });

4. 示例

4.1 添加点击事件监听器
const button = document.querySelector('button');

function handleClick(event) {
  console.log('按钮被点击了');
}

button.addEventListener('click', handleClick);
4.2 添加键盘事件监听器
document.addEventListener('keydown', function(event) {
  console.log(`按下的键是:${event.key}`);
});
4.3 使用选项参数
const link = document.querySelector('a');

link.addEventListener('click', function(event) {
  event.preventDefault();
  console.log('链接点击,但默认行为被阻止');
}, { passive: false });

5. 注意事项

  • 事件类型区分大小写'click''Click' 是不同的事件类型。
  • this 的指向:在事件处理程序中,this 默认指向触发事件的元素。
  • 事件处理程序的移除:使用 addEventListener() 添加的事件监听器,需要使用 removeEventListener() 进行移除。

三、removeEventListener() 方法

1. 方法简介

removeEventListener() 方法用于从目标对象上移除先前通过 addEventListener() 添加的事件监听器。

2. 语法

target.removeEventListener(type, listener[, options]);
  • target:要移除事件监听器的目标对象。
  • type:要移除的事件类型。
  • listener:要移除的事件处理程序(必须与添加时的函数引用相同)。
  • options(可选):一个对象,指定事件监听器的属性,必须与添加时的选项匹配。

3. 参数详解

3.1 type

addEventListener() 中的 type 参数相同,指定要移除的事件类型。

3.2 listener

要移除的事件处理程序,必须是与添加时相同的函数引用。

3.3 options

可选参数,必须与添加事件监听器时的选项相同。

4. 示例

4.1 移除事件监听器
function handleClick(event) {
  console.log('按钮被点击了');
}

// 添加事件监听器
button.addEventListener('click', handleClick);

// 移除事件监听器
button.removeEventListener('click', handleClick);
4.2 使用匿名函数的问题

如果使用匿名函数作为事件处理程序,无法通过 removeEventListener() 进行移除,因为无法引用同一个函数。

// 添加匿名函数作为事件处理程序
button.addEventListener('click', function() {
  console.log('按钮被点击了');
});

// 无法移除匿名函数事件处理程序
button.removeEventListener('click', function() {
  console.log('按钮被点击了');
}); // 不会移除事件监听器

解决方法:使用命名函数或将匿名函数赋值给变量。

5. 注意事项

  • 函数引用必须相同removeEventListener() 中的 listener 参数,必须与 addEventListener() 中的 listener 参数引用同一个函数。
  • 选项参数必须匹配:如果添加事件监听器时使用了选项参数,移除时也需要提供相同的选项。
  • 无法移除匿名函数:因为无法引用同一个匿名函数。

四、常见事件及应用

1. 鼠标事件

1.1 click 事件

当用户单击(按下并释放)鼠标按钮时触发。

应用示例:按钮点击、链接点击。

button.addEventListener('click', function(event) {
  console.log('按钮被点击了');
});
1.2 dblclick 事件

当用户双击鼠标按钮时触发。

应用示例:双击编辑、全选文本。

element.addEventListener('dblclick', function(event) {
  console.log('元素被双击了');
});
1.3 mouseovermouseout 事件
  • mouseover:当鼠标指针移入元素或其子元素时触发。
  • mouseout:当鼠标指针移出元素或其子元素时触发。

应用示例:显示/隐藏提示信息、菜单展开。

element.addEventListener('mouseover', function(event) {
  console.log('鼠标移入元素');
});

element.addEventListener('mouseout', function(event) {
  console.log('鼠标移出元素');
});
1.4 mouseentermouseleave 事件
  • mouseenter:当鼠标指针移入元素时触发,不会冒泡,也不会在子元素上触发。
  • mouseleave:当鼠标指针移出元素时触发。

应用示例:与 mouseovermouseout 类似,但更精确地控制事件触发。

element.addEventListener('mouseenter', function(event) {
  console.log('鼠标进入元素');
});

element.addEventListener('mouseleave', function(event) {
  console.log('鼠标离开元素');
});
1.5 mousemove 事件

当鼠标指针在元素内部移动时持续触发。

应用示例:绘图、拖拽、游戏交互。

element.addEventListener('mousemove', function(event) {
  console.log(`鼠标位置:(${event.clientX}, ${event.clientY})`);
});

2. 键盘事件

2.1 keydown 事件

当用户按下键盘按键时触发,持续触发(长按时会重复)。

应用示例:快捷键、输入验证。

document.addEventListener('keydown', function(event) {
  console.log(`按下的键是:${event.key}`);
});
2.2 keyup 事件

当用户释放键盘按键时触发。

应用示例:输入完成后处理、组合键检测。

document.addEventListener('keyup', function(event) {
  console.log(`释放的键是:${event.key}`);
});
2.3 keypress 事件

当用户按下可打印字符键时触发,已废弃,不建议使用。

3. 表单事件

3.1 submit 事件

当表单提交时触发。

应用示例:验证表单数据、阻止默认提交。

form.addEventListener('submit', function(event) {
  event.preventDefault(); // 阻止表单的默认提交行为
  console.log('表单提交');
});
3.2 change 事件

当表单控件的值改变并失去焦点时触发。

应用示例:动态更新、表单验证。

input.addEventListener('change', function(event) {
  console.log(`新的值是:${event.target.value}`);
});
3.3 focusblur 事件
  • focus:当元素获得焦点时触发。
  • blur:当元素失去焦点时触发。

应用示例:高亮输入框、验证输入。

input.addEventListener('focus', function(event) {
  console.log('输入框获得焦点');
});

input.addEventListener('blur', function(event) {
  console.log('输入框失去焦点');
});

4. 触摸事件(移动设备)

4.1 touchstarttouchmovetouchend

当在触摸屏上触摸时触发。

应用示例:移动端手势、滑动、缩放。

element.addEventListener('touchstart', function(event) {
  console.log('触摸开始');
});

element.addEventListener('touchmove', function(event) {
  console.log('触摸移动');
});

element.addEventListener('touchend', function(event) {
  console.log('触摸结束');
});

5. 窗口事件

5.1 load 事件

当页面全部加载完成时触发,包括所有资源(图片、脚本等)。

应用示例:初始化操作、加载动画。

window.addEventListener('load', function(event) {
  console.log('页面加载完成');
});
5.2 resize 事件

当窗口大小改变时触发。

应用示例:响应式布局、调整元素大小。

window.addEventListener('resize', function(event) {
  console.log(`窗口尺寸:${window.innerWidth} x ${window.innerHeight}`);
});
5.3 scroll 事件

当滚动条位置发生变化时触发。

应用示例:懒加载、滚动动画。

window.addEventListener('scroll', function(event) {
  console.log(`滚动位置:${window.scrollY}`);
});

五、实践示例

1. 实现按钮点击计数器

<button id="countButton">点击我</button>
<p>你已经点击了 <span id="count">0</span> 次。</p>
const button = document.getElementById('countButton');
const countDisplay = document.getElementById('count');
let count = 0;

function updateCount() {
  count++;
  countDisplay.textContent = count;
}

button.addEventListener('click', updateCount);

2. 实现图片轮播效果

<img id="slider" src="image1.jpg" alt="轮播图" width="500">
<button id="prevButton">上一张</button>
<button id="nextButton">下一张</button>
const images = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
let currentIndex = 0;

const slider = document.getElementById('slider');
const prevButton = document.getElementById('prevButton');
const nextButton = document.getElementById('nextButton');

function showImage(index) {
  slider.src = images[index];
}

prevButton.addEventListener('click', function() {
  currentIndex = (currentIndex - 1 + images.length) % images.length;
  showImage(currentIndex);
});

nextButton.addEventListener('click', function() {
  currentIndex = (currentIndex + 1) % images.length;
  showImage(currentIndex);
});

3. 表单验证示例

<form id="signupForm">
  <label for="email">邮箱:</label>
  <input type="email" id="email" required>
  <button type="submit">注册</button>
</form>
<p id="message"></p>
const form = document.getElementById('signupForm');
const emailInput = document.getElementById('email');
const message = document.getElementById('message');

form.addEventListener('submit', function(event) {
  event.preventDefault(); // 阻止表单默认提交
  const email = emailInput.value;
  if (validateEmail(email)) {
    message.textContent = '注册成功!';
  } else {
    message.textContent = '请输入有效的邮箱地址。';
  }
});

function validateEmail(email) {
  // 简单的邮箱验证正则表达式
  const re = /\S+@\S+\.\S+/;
  return re.test(email);
}

4. 实现拖拽效果

<style>
  #dragItem {
    width: 100px;
    height: 100px;
    background-color: skyblue;
    position: absolute;
    cursor: move;
  }
</style>
<div id="dragItem"></div>
const dragItem = document.getElementById('dragItem');
let isDragging = false;
let offsetX, offsetY;

dragItem.addEventListener('mousedown', function(event) {
  isDragging = true;
  offsetX = event.clientX - dragItem.offsetLeft;
  offsetY = event.clientY - dragItem.offsetTop;
});

document.addEventListener('mousemove', function(event) {
  if (isDragging) {
    dragItem.style.left = `${event.clientX - offsetX}px`;
    dragItem.style.top = `${event.clientY - offsetY}px`;
  }
});

document.addEventListener('mouseup', function(event) {
  isDragging = false;
});

六、事件传播和委托

1. 事件传播机制

JavaScript中的事件传播分为三个阶段:

  1. 捕获阶段:从最顶层(window)向目标元素传播。
  2. 目标阶段:在目标元素上触发事件处理程序。
  3. 冒泡阶段:从目标元素向上传播到最顶层。

默认情况下,事件处理程序在冒泡阶段被触发。

2. 事件委托

事件委托是一种利用事件冒泡机制,将事件监听器添加到父元素上,而不是为每个子元素添加监听器的方法。

示例:为列表中的每个项添加点击事件。

<ul id="list">
  <li>项目 1</li>
  <li>项目 2</li>
  <li>项目 3</li>
</ul>
const list = document.getElementById('list');

list.addEventListener('click', function(event) {
  if (event.target && event.target.nodeName === 'LI') {
    console.log(`点击了:${event.target.textContent}`);
  }
});

参考资料


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

It'sMyGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值