第 4 章 · 事件与交互
第 2 章学会了「怎么画」,第 3 章学会了「怎么摆」——但画得再好、摆得再正,那也只是一张静态的画。界面之所以是界面,在于它会回应:你点它,它亮;你划它,它滚;你捏它,它缩。这一章追着一个问题挖到底:从你手指按下去的那一瞬间,到界面做出回应,屏幕背后到底走过了哪条路?这条路一共六段:事件先在唯一的队列里排队(循环),再沿 DOM 树走完三段旅程(传播),它说着不同设备的方言(输入),需要被翻译成用户真正的意图(手势);键盘世界另有一条路,靠一盏追光灯引路(焦点);而这条路修到终点,必须是「每个人都能走」(无障碍)。六节读完,「点击背后发生了什么」这句话,对你来说将不再是一团黑箱,而是一条能逐段讲清的流水线。
本章要回答什么
界面为什么会「卡死」——点了没反应,连动画都停了?click 到底发生在了哪个元素身上,为什么父元素也能听到?一个列表一万行,难道要挂一万个监听器?鼠标、触摸屏、手写笔、手柄,各说各的话,程序怎么统一接待?长按和拖拽同时发生,听谁的?把鼠标拔掉、屏幕关掉,盲人用户怎么用你的界面——他们「看到」的世界长什么样?这六个问题,就是六节的入口。
这一章像一栋大楼的物业系统。
事件循环是物业前台唯一的值班员——所有报修请求排成一条队,一次只办一件,谁插队谁卡死整栋楼;
冒泡与捕获是一份报修单的流转——先从顶楼逐层下发,再从一楼逐层回执,沿途每层都有权处理或放行;
输入设备是五种报修方式——电话、短信、微信、上门、托人带话,说得再杂,前台都要翻成同一张工单;
手势识别是老值班员听敲门——轻敲是查访、连敲是着急、按着不松是东西卡住了,动作背后是意图;
焦点是大楼唯一一部电梯的呼梯权——同一时刻只认一个人,排队规矩全写在名单上;
无障碍是把全楼的台阶都修成坡道——推轮椅的、拉行李的、推婴儿车的,走的都是同一条路。
本章的六节
事件循环 Event Loop
主线程、任务队列、微任务、16.7 毫秒一帧——界面为什么会「卡死」的终极答案。
冒泡与捕获
事件的三个阶段、stopPropagation 与 preventDefault、事件委托——一个监听器管一千行。
输入设备
鼠标、键盘、触摸、笔、手柄——五种方言各说什么,Pointer Events 怎么统一翻译。
手势识别
点击、长按、拖拽、双指缩放——状态机、阈值与仲裁,从动作里读出意图。
焦点与键盘导航
Tab 顺序、焦点陷阱、roving tabindex、快捷键——拔掉鼠标,界面照样能用。
无障碍 A11y
屏幕阅读器、语义化、ARIA、对比度、动效安全——让所有人都能走进这扇门。
六节是一条事件的一生
1. 循环 · 产地
事件醒来第一件事:排队。主线程一次只办一件,办不完就卡——异步是唯一的解药。
2. 传播 · 旅程
捕获下行、命中目标、冒泡上行——委托就藏在回程的车上。
3. 设备 · 方言
五种设备各说各话,Pointer Events 把它们翻成同一本账。
4. 手势 · 意图
位移过阈值才算拖、静止够久才算长按——状态机把动作翻译成想法。
5. 焦点 · 另一条路
键盘不走指针的路,它跟着一盏追光灯——焦点就是键盘世界的地址。
6. 无障碍 · 终点
路修得再快,也要人人能走——坡道效应收官:为极端修的路,所有人都在走。
学之前先记住这一点
- 界面不会自己动一切「动」都是对事件的响应——而处理事件的主线程只有一个,长任务是卡死的唯一元凶。
- 别挂一万个监听器事件会冒泡,父节点上的一个监听器能接住所有子元素——委托是工程标配,不是优化彩蛋。
- 动作不值钱,意图才值钱用户按下的从来不是「click」,而是「我想打开」——中间隔着一台状态机。
- 指针之外还有一条路键盘和读屏走的是焦点这条路——两条路都通,界面才算能用。
- 交互的终点是无障碍「每个人都能点」不是加分项,是验收线——语义、焦点、对比度,一个都不能少。