欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 前端JavaScript-嵌套事件

前端JavaScript-嵌套事件

2025/5/22 6:10:33 来源:https://blog.csdn.net/2301_78856868/article/details/148125116  浏览:    关键词:前端JavaScript-嵌套事件

点击

如果在多层嵌套中,对每层都设置事件监视器,试试看

<!DOCTYPE html>
<html lang="cn">
<body><div id="container"><button>点我!</button></div><pre id="output"></pre><script src="button.js"></script>"
</body>
</html>
const output = document.querySelector("#output");
const container = document.querySelector("#container");
const button = document.querySelector("button");function handleClick(e) {output.textContent += `你在 ${e.currentTarget.tagName} 元素上进行了点击\n`;
}document.body.addEventListener("click", handleClick);
container.addEventListener("click", handleClick);
button.addEventListener("click", handleClick);

在 JS 脚本中先用 querySelector (querySelector是JS原生提供的DOM元素查找函数,是DOM API中的一部分,它的作用是通过 CSS选择器 定位匹配的第一个元素)来确定了 output 和 container 位置并赋值给变量

(CSS选择器通过特定语法匹配HTML元素并应用样式,通过 .class 、 #id ,将其应用到JS里面来提取元素的好处就是不用更改语法)

接着设置了自定义函数 handleClick(e) ,参数e是一个事件对象(Event object),这是浏览器自动传递给事件处理函数的一个参数,比如 button.addEventListener("click", handleClick); 这告诉了如果点击了button那么就调用 handleClick,这时会自动生成一个事件对象,其中 e.currentTarget 就是监听对象 button ,而 e.currentTarget.tagName 就是 事件监听器对象元素的标签名

这个事件并不是通过 alert 实现输出,而是直接更改 DOM元素output 的值,这会在点击后直接显示

你在 BUTTON 元素上进行了点击
你在 DIV 元素上进行了点击
你在 BODY 元素上进行了点击

可以看到三层元素都触发了单击事件

可以观察到

        最先触发的是按钮的

        然后是其父元素...

可以理解为:事件从点击的最里层的元素冒泡而出

.target 和 .currentTarget 有什么区别

event.target 和 event.currentTarget 都指向DOM元素,但是

        event.target 指向的是触发事件的元素,在冒泡过程中是保持不变的

        event.currentTarget 指向的是事件处理程序当前附加到的元素,也就是当前处理层的元素

注册而非轮询

也许你会好奇,为什么我都没有加 while ,我一旦触发事件还是会有相应的结果呢?

其实事件监视器是被动的、称为“事件驱动程序”的模式

在浏览器内部有一个事件循环机制,它会不断地持续检查队列中是否有事件要处理

异步处理:当用户触发事件时,浏览器会将这个事件放入事件队列,事件循环一旦检测到队列中有事件就会用相应的事件处理(异步处理是一种编程和系统设计模式,其核心在于非阻塞执行,在发起耗时操作,如IO、网络请求等后,程序不会等待操作完成,而是继续执行后续任务,等操作完成再回调

(不阻塞:不会阻塞主线程或消耗CPU资源来主动检查事件是否发生,只有事件触发时相关代码才会执行)

在线程、线程池、异步-CSDN博客有更详细说明

隐藏

我们想要实现隐藏视频,只有在点击按钮的时候才显现,这时候点击视频会开始播放,点击除视频外的地方会隐藏视频

<button>显示视频</button><div class="hidden"><video><source src="/shared-assets/videos/flower.webm" type="video/webm" /><p>你的浏览器不支持 HTML 视频,这里有视频的<a href="rabbit320.mp4">替代链接</a>。</p></video>
</div>
const btn = document.querySelector("button");
const box = document.querySelector("div");
const video = document.querySelector("video");btn.addEventListener("click", () => box.classList.remove("hidden"));
video.addEventListener("click", () => video.play());
box.addEventListener("click", () => box.classList.add("hidden"));

在 JS 里面添加了三个 'click' 事件处理器

classList 是 DOM 元素对象的一个属性,提供了一个便捷的方式来操作元素的类(class属性),它是 DOMTokenList 类型的对象,用于添加、删除、检查和切换 CSS 类

button 的点击处理器会通过 box 的 classList 移除 div 的 "hidden" 类

在运行的时候会发现点击按钮的时候会显示视频,但是点击视频的时候盒子又被隐藏了,这是因为 video 在 div 里面,所以点击视频会触发 video 的事件,也会触发 div 的事件

这时候我们就想要阻止 video 向外界的感染,需要通过 stopPropagation( ) 方法

const btn = document.querySelector("button");
const box = document.querySelector("div");
const video = document.querySelector("video");btn.addEventListener("click", () => box.classList.remove("hidden"));video.addEventListener("click", (event) => {event.stopPropagation();video.play();
});box.addEventListener("click", () => box.classList.add("hidden"));

可以看到我们在 video 的事件里面添加了 event.stopPropagation();

事件捕捉

跟冒泡顺序相反,从最外层到最里面,想实现这样的操作只需要将 capture 参数设置为 true

比如刚开始的按钮例子

document.body.addEventListener("click", handleClick, { capture: true });
container.addEventListener("click", handleClick, { capture: true });
button.addEventListener("click", handleClick);

顺序就发生了颠倒

你在 BODY 元素上进行了点击
你在 DIV 元素上进行了点击
你在 BUTTON 元素上进行了点击

事件委托

默认冒泡的话,我们可以通过子元素感染父元素,而不用一个个设置了,不直接在子元素上设置监听器,而是将监听器设置在父元素上,通过冒泡让父元素监听来自子元素的事件,

<!DOCTYPE html>
<html lang="en"></html>
<body><link href="button.css" rel="stylesheet" type="text/css"><div id="container"><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div></div><script src="button.js"></script>"
</body>
</html>
.tile {height: 100px;width: 25%;float: left;
}
function random(number) {return Math.floor(Math.random() * number);
}function bgChange() {const rndCol = `rgb(${random(255)}, ${random(255)}, ${random(255)})`;return rndCol;
}const container = document.querySelector("#container");container.addEventListener("click", (event) => {event.target.style.backgroundColor = bgChange();
});

在这个例子中有很多 .title 元素在 #container 内

但是没有对每个元素添加事件监听器

而是在父元素 #container 上加了监听器,通过 event.target 来确定是哪个子元素触发了事件,并更改其 style.backgroundColor 为 bgChange

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词