前端学习16 JavaScript事件监听

在 JavaScript 编程中,事件监听是一种非常重要的机制,它允许我们在特定的事件发生时执行特定的代码。事件监听器可以用于响应用户的操作(如点击、鼠标移动、键盘输入等),也可以用于响应浏览器的事件(如页面加载完成、窗口大小改变等)。本文将详细介绍 JavaScript 事件监听的相关知识,并通过丰富的示例帮助你更好地理解。

1.事件监听的概念

事件监听器是一种函数,它在特定事件发生时被调用。事件监听器可以附加到 DOM 元素上,当该元素上发生指定的事件时,事件监听器就会被触发。

2.事件监听的类型

JavaScript 支持多种类型的事件,常见的事件类型包括:

  • 鼠标事件:click, dblclick, mousemove, mouseover, mouseout, mousedown, mouseup
  • 键盘事件:keydown, keyup, keypress
  • 表单事件:submit, reset, focus, blur, change, input
  • 窗口事件:load, unload, resize, scroll
  • 触摸事件:touchstart, touchend, touchmove, touchcancel

3.事件监听的添加

在 JavaScript 中,可以使用 addEventListener 方法为 DOM 元素添加事件监听器。addEventListener 方法有三个参数:事件类型、事件处理函数和可选的选项对象。

element.addEventListener(eventType, eventHandler, options);

下面是对一个按钮添加点击事件监听器:


let button = document.getElementById('myButton');
button.addEventListener('click', function() {
  alert('Button clicked!');
});

为了提高代码的可读性和可维护性,可以将事件处理函数定义为一个命名函数:

let button = document.getElementById('myButton');

function handleClick() {
  alert('Button clicked!');
}

button.addEventListener('click', handleClick);

3.1 选项对象(可选)

addEventListener 方法的第三个参数是一个选项对象,可以包含一下属性:

  • capture:布尔值,表示事件是否在捕获阶段触发(默认为false)。
  • once:布尔值,表示事件处理函数是否只执行一次(默认为false)。
  • passive:布尔值,表示事件处理函数是否永远不会调用preventDefault(默认为false)。
button.addEventListener('click', handleClick, {
  capture: true,
  once: true,
  passive: false
});

4.移除事件监听器

可以使用 removeEventListener 方法移除事件监听器。需要注意的是,移除事件监听器时必须使用与添加时相同的函数引用。

button.removeEventListener('click', handleClick);

5. 事件对象

在事件处理函数中,可以通过参数访问事件对象。事件对象包含有关事件的详细信息,如事件类型、目标元素、鼠标位置等。

function handleClick(event) {
  console.log('Event type:', event.type);
  console.log('Target element:', event.target);
  console.log('Mouse position:', event.clientX, event.clientY);
}

button.addEventListener('click', handleClick);

当事件发生时,监听器会按照它们被添加的顺序执行。

在 JavaScript 中,addEventListener 方法只能同时为一个特定事件添加一个监听器。

6. 事件传播

事件传播分为三个阶段:捕获阶段、目标阶段和冒泡阶段。默认情况下,事件监听器在冒泡阶段触发。可以通过设置capture选项在捕获阶段触发事件监听器。

冒泡阶段(bubbling):当一个元素接收到事件的时候,会把它接收到的事件传给它的父元素,然后再传给父元素的父元素,一直传递到最顶层的 Document 对象。这种事件处理方式就是事件冒泡。大多数事件都会冒泡。简单来说,如果你点击了一个按钮,那么你不仅仅只是点击了按钮,同时也点击了包含这个按钮的所有父元素。

捕获阶段(capturing):事件捕获与事件冒泡恰好相反,事件会从最外层元素先接收,然后向内层嵌套的元素传递,最后达到最精确的元素。

document.getElementById('parent').addEventListener('click', () => {
  console.log('父元素被点击');
});

document.getElementById('child').addEventListener('click', () => {
  console.log('子元素被点击');
});

//输出为:
//子元素被点击
//父元素被点击

说明事件从子元素触发后会“冒泡”到父元素,父元素也会触发 click。

而捕获阶段只需要在addEventListener的第三个参数传递true

element.addEventListener('click', handler, true); // 捕获阶段
element.addEventListener('click', handler, false); // 冒泡阶段(默认)

7.阻止事件传播

7.1 event.stopPropagation()

阻止事件继续冒泡或捕获,即事件不会再向上传播(冒泡阶段)或向下传播(捕获阶段)。

但是不会影响:

当前元素上的其他事件监听器(如果有多个监听器,还是会依次执行)

事件的默认行为(如表单提交、a 标签跳转等)

7.2 event.stopImmediatePropagation()

在 stopPropagation() 的基础上多了一层控制,它会:

阻止事件继续传播(冒泡/捕获都停)

阻止当前元素上其他事件监听器的执行

7.3 event.preventDefault()

阻止事件的默认行为,不阻止事件传播。

阻止表单自动提交、阻止 a 标签跳转、阻止右键菜单弹出(contextmenu)、阻止 input checkbox 自动选中等

#前端#
全部评论

相关推荐

锐明技术一面:二面要线下 不想去没去1、什么是原型链2、vue2和vue3的区别3、三种存储方式有哪些localstorage和sessionstorage区别4、css垂直居中的方式5、组建之间的通信方式6、promise和settimeout的区别7、实现双向绑定的原理8、加密算法的区别9、webRTC反问意见:没有抓清楚回答的重点,面试官提问的重点小鹅通一面:二面基本都是问项目没有八股 已oc没去1.简单说一下webRTC的整个项目的实现2.为什么考虑使用虚拟列表3.虚拟列表是怎么实现的(实现原理)  可以考虑分页4.说一下怎么判断是否在可视区域5.JS常用的数据结构6.怎么理解闭包7.js继承怎么实现的8.js继承和C++继承有什么区别9.http常见的协议头10.日常访问网页的时候 有时候访问图片、视频 会让你下载 有时候又让你在网页预览 你怎么做,怎么理解的反问意见:需要加强业务上的思考。比如虚拟列表可能会占用内存等腾讯音乐一面:(kpi两次 面完秒挂 没有手撕)1.怎么解决跨域的问题?2.项目难点3.单点登录4.项目最大的收获5.Js数据类型6.怎么判断数组类型7.数组怎么去重(set怎么转数组)8.字符串怎么转为数组9.数组排序(指定升序排序)10.web页面 有哪些策略进行性能优化11.说一下CDN让访问变快的原理12.域名解析的过程13.浏览器缓存的原理14.什么情况下会命中强缓存(协商缓存)问的很细15.图片懒加载实现原理(需要更加底层)16.说一下浏览器dom渲染过程17.Http2/http3比http1优化的地方18.http状态码19.解决跨域的方法20.为什么有跨域的问题21.Xss攻击(怎么攻击 怎么解决这个攻击)22.为什么输入脚本可以攻击23.Js实现继承(很细)24.为什么父类的引用类型属性会被所有子类共享25.深拷贝实现26.如何在全局捕获js异常27.衡量页面性能的指标(需要答很多)28.Nodejs react反问意见:需要了解网络相关的底层原理美团一二面 已oc 决定去美团了八股基本都是类似的 手撕数组去重 能写多少写多少 用map去重第二次手撕是路径匹配 需要处理./ ../ 感觉美团想要你的话 问项目会问的比较多反问主要是问的他们那边的业务
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务