点击Start按钮时HTML的click事件意外触发,求原因解析
问题原因分析
你的问题核心在于DOM事件的冒泡机制,以及事件处理函数的同步执行顺序:
- 点击
Start按钮时,首先触发按钮自身的click事件处理函数:- 先打印
start, from button onClick event. - 紧接着同步调用
start(),完成<html>元素的click事件绑定
- 先打印
- 按钮的事件处理函数执行完毕后,事件会沿着DOM树向上冒泡(按钮→body→html→document)
- 此时
<html>已经绑定了click事件处理函数,事件冒泡到这里时就会触发它,打印对应日志
你原本误以为绑定<html>事件的动作是在按钮点击事件结束后才完成,但实际上按钮的事件处理函数是同步执行的——绑定代码在按钮事件的同步流程里就已经完成,等事件冒泡到<html>时,监听已经存在,自然会触发。
解决办法
如果不想让<html>的click事件在点击按钮时被触发,有两种常用方案:
方案1:阻止按钮事件冒泡
在按钮的事件处理函数中,通过事件对象阻止事件向上传递:
const loadPage = () => { $("#start-button").on("click", function(e) { console.log("start, from button onClick event.") start(); e.stopPropagation(); // 阻止事件冒泡到上层元素 }); }
方案2:异步绑定<html>事件
把绑定<html>事件的逻辑放到异步队列中,等事件冒泡完成后再执行绑定:
const start = () => { setTimeout(() => { $("html").on("click", function() { console.log("click, from html onClick event.") }); }, 0); };
内容的提问来源于stack exchange,提问作者Daniel So Ho Kit
相关产品推荐
相关产品推荐

