事件对象:读懂神经信号


文档摘要

4.2 事件对象:读懂神经信号 接线是上一节的事,这一节读信号本身。每当事件发生,浏览器都会造出一个事件对象,沿传播路线送达每一个监听器——它是神经上跑的那份信号单:谁触发的、在页面什么坐标、按的是哪个键、要不要拦下来。处理器签名里的第一个参数 拿到的就是它。读懂这张单子,交互逻辑才从"能触发"升级到"可控"。 本节摘要:事件对象的核心字段分三组——定位组( 、 、 、坐标),内容组(按键、输入值、携带的 ),控制组( 、 、 三道闸门)。分清"谁被点中"与"谁在听诊"是读单的第一课。 一张信号单上的关键字段 字段虽多,按用途分三组就清楚了。下面把每组的成员和分工画在一起: 对着标本页把定位组读一遍: 内容组在键盘与表单事件里出场, 与 的用法放在 4.3 节结合具体事件讲;

4.2 事件对象:读懂神经信号

接线是上一节的事,这一节读信号本身。每当事件发生,浏览器都会造出一个事件对象,沿传播路线送达每一个监听器——它是神经上跑的那份信号单:谁触发的、在页面什么坐标、按的是哪个键、要不要拦下来。处理器签名里的第一个参数 event 拿到的就是它。读懂这张单子,交互逻辑才从"能触发"升级到"可控"。

本节摘要:事件对象的核心字段分三组——定位组(typetargetcurrentTarget、坐标),内容组(按键、输入值、携带的 data),控制组(preventDefaultstopPropagationstopImmediatePropagation 三道闸门)。分清"谁被点中"与"谁在听诊"是读单的第一课。

一张信号单上的关键字段

字段虽多,按用途分三组就清楚了。下面把每组的成员和分工画在一起:

对着标本页把定位组读一遍:

$('#queue').on('click', '.item', function (event) { console.log(event.type); // 'click' console.log(event.target); // 被点中的最深元素,可能是条目里的 span console.log(event.currentTarget); // 当前听诊者,委托场景下是匹配 .item 的那条 console.log(event.pageX, event.pageY); // 相对文档左上角的坐标 });

内容组在键盘与表单事件里出场,whichkey 的用法放在 4.3 节结合具体事件讲;控制组是本节的重头戏,值得单独开一刀。

target 与 currentTarget:谁被点中,谁在听诊

这两个字段是委托机制的概念基石,先用一句话立住:target 是患者,currentTarget 是拿着听诊器的你。直接绑定场景两者通常相同,委托场景立刻分家——监听器绑在容器上,点中的却是容器里的某个子元素:

// 监听器绑在 ul 上,但只在点中条目时行动 $('#queue').on('click', function (event) { if ($(event.target).closest('.item').length) { console.log('点中的是条目内部:', event.target.tagName); console.log('听诊的是队列容器:', event.currentTarget.tagName); } });

为什么委托场景要配合 closest?因为 target 是"点得最深"的那个元素——点中的可能是条目里的加粗文字而不是条目本身。$(event.target).closest('.item') 的意思是"从患者往最近的条目退",退得到就说明这次点击属于某条目。这行代码是 4.4 节委托术的心脏,先在这里认识它。

三道闸门:拦默认、断上报、就地封锁

控制组的三道闸门名字相近,职权完全不同,混用是排错榜的常客:

// 闸门一:取消默认行为。信号继续传,浏览器的既定动作不做了 $('a.confirm').on('click', function (event) { if (!window.confirm('确定离开?')) { event.preventDefault(); // 链接不跳转,但冒泡照常 } }); // 闸门二:切断冒泡。父级听不到这次事件,默认行为照做 $('.tag').on('click', function (event) { event.stopPropagation(); // 点标签不触发外层条目的逻辑 }); // 闸门三:就地封锁。冒泡切断,且同一元素上排在自己之后的监听器也不执行 $('.hot').on('click', function (event) { event.stopImmediatePropagation(); }); $('.hot').on('click', function () { console.log('这条永远不会打印'); });

三道闸门的适用口诀:改的是浏览器行为用闸门一,改的是其他监听器的知情权用闸门二,还要封杀同元素后续监听器才用闸门三。反例记一个:表单校验里拦提交该用 preventDefault——提交事件的默认行为是把数据发走;有人顺手写了 stopPropagation,数据照发不误,校验白做。

给处理器携带参数:data 字段

绑定时可以把参数随线附带,回调里从 event.data 取出:

$('#refresh').on('click', { source: 'remote', limit: 20 }, function (event) { console.log(event.data.source, event.data.limit); // 'remote' 20 });

同一处理器服务多个元素、各元素带不同配置时,这个机制比在回调里查元素属性干净得多。原生 addEventListener 没有对应物,常见替代是 bind 出偏函数或闭包包一层——能做,但 event.data 的签名更整齐。

原生对照与历史包袱

事件对象如今是 DOM 标准的一部分,targetcurrentTarget、三道闸门在原生里同名同义——这块 jQuery 没有另造方言,学一次两边通用。历史上的差异集中在兼容层:老 IE 把事件对象挂在全局 window.event 上、用 returnValue 拦默认、用 cancelBubble 断冒泡,这些正是当年非用类库不可的理由之一。今天维护的现代代码里已见不到它们,读十几年前的老代码时再对号入座即可。

按键信息要留个心眼:which 是 jQuery 的统一封装,原生标准是键盘事件看 key(键名字符)与 code(物理键位),鼠标事件看 button(按下的是哪个键位)。新代码建议直接用原生字段,which 认得就行。

要点复盘

  • 事件对象三组字段:定位(type、双 target、坐标)、内容(按键、data)、控制(三道闸门)。
  • target 是被点中的最深元素,currentTarget 是正在执行的监听器所属元素;委托场景必分家。
  • 委托场景判断归属用 $(event.target).closest(sel),这行是下一节的心脏。
  • 闸门口诀:拦浏览器默认用 preventDefault,断他人知情用 stopPropagation,还要封同元素后续监听才用 stopImmediatePropagation
  • 表单校验拦提交是 preventDefault 的本职;写错成断冒泡,数据照发。
  • data 参数让同一处理器带不同配置上岗,原生要用闭包变通。

信号读得懂了,下一节盘点各条神经的敏感区:常用事件类型有哪些,成对事件的先后次序怎么排。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U