前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库getCoalescedEvents pointermove 作用
浏览器事件系统

getCoalescedEvents 能补回哪些 pointermove 轨迹?

浏览器可能把多次指针位置更新合成一次 pointermove。getCoalescedEvents() 可取出这次事件中合并的细分样本,让绘图线条更贴近真实轨迹;它不会直接提高显示器帧率。

前端进阶之旅 · 一题精讲更新于 2026.09.29
浏览器#事件系统
先看核心答案读代码示例
理解线索

派发更少,轨迹点仍可保留

  1. pointermove指针移动的公开事件
  2. 合并事件浏览器聚合的多次位置更新
  3. getCoalescedEvents()读取合并前的细粒度样本

该方法的兼容性并非所有主流环境都一致,且部分环境要求安全上下文。

核心回答

先记住这个答案

指针设备可能比浏览器派发 pointermove 的频率采样得更密。浏览器把若干更新合成一次公开事件以减少事件处理开销,getCoalescedEvents() 让绘图应用在这次回调里拿到更多中间坐标,从而画出更细腻的轨迹。它改善的是轨迹精度,不保证屏幕刷新率或应用每秒绘制帧数变高。

  • 浏览器可合并高频指针更新
  • 方法返回被合并的指针事件样本
  • 绘图可减少快速移动时的折线缺口
  • 需检查浏览器支持与安全上下文

手写笔快速划线为何会断角

如果每次 pointermove 只画公开事件的一个坐标,高速移动时相邻点距离很大,曲线容易变成明显折线。读取合并样本后,可以按顺序把中间点接上。

逐个消费合并样本JavaScript
const pad = document.querySelector('#pad')
const ctx = pad.getContext('2d')
let drawing = false, lastX = 0, lastY = 0
pad.addEventListener('pointerdown', event => {
  drawing = true; pad.setPointerCapture(event.pointerId)
  const box = pad.getBoundingClientRect()
  lastX = event.clientX - box.left; lastY = event.clientY - box.top
})
pad.addEventListener('pointermove', event => {
  if (!drawing) return
  const box = pad.getBoundingClientRect()
  ctx.beginPath()
  ctx.moveTo(lastX, lastY)
  for (const point of event.getCoalescedEvents?.() ?? [event]) {
    lastX = point.clientX - box.left; lastY = point.clientY - box.top
    ctx.lineTo(lastX, lastY)
  }
  ctx.stroke() // 每批样本只描画新线段
})
for (const type of ['pointerup', 'pointercancel']) pad.addEventListener(type, () => { drawing = false })

不支持该方法时使用当前事件作为回退,至少能继续绘图。示例用 getBoundingClientRect() 把视口坐标转成画布坐标,并假定画布的绘图尺寸与 CSS 显示尺寸相同;若再用 CSS 缩放画布,还需按两者比例换算。setPointerCapture() 让按下后的指针暂时离开画布时,后续移动仍能交给这张画布处理。 每次移动先从上一批的末点开启一条新路径,只描画本批新增线段;若不调用 beginPath(),半透明笔刷会在后续移动中反复描粗旧线段。拿到更多采样点也意味着更多绘制工作,复杂画板可累计点后按帧批量绘制。

帧率与采样精度不是同一指标

屏幕刷新、浏览器绘制帧和指针硬件采样各有频率。getCoalescedEvents() 提供的是更完整的输入轨迹,不会改变显示器刷新速度。它的收益主要体现在笔迹平滑和快速手势分析。

该 API 的支持范围有差异,面向普通网页时要留降级路径,并在 HTTPS 等目标运行环境实测。并非所有指针动作都需要读取细粒度样本;按钮点击完全没有这个需求。

画布还要区分 CSS 尺寸与绘图缓冲区尺寸。高 DPR 设备上若只把样式设成 500 像素宽、却让内部位图保持默认尺寸,笔迹即使采样很密也会模糊或错位。实际画板可按设备像素比设置缓冲区,再统一坐标换算;getCoalescedEvents() 只补输入点,不能替代这一步。

若存在多指触摸,单个 drawing 布尔值也不够,需要用 pointerId 追踪正在绘制的那支笔。示例只讨论单指笔迹,生产组件应在取消、丢失指针捕获等路径收尾,避免下一次移动接到上一条线段。

回答前,多想一步

容易答错的地方

说它能直接提升浏览器帧率
它提供合并前的输入样本;帧率还取决于绘制成本和显示管线。
不检查支持就直接调用
部分环境没有这个方法或受安全上下文限制,需要回退。
试着用自己的话回答

面试官还会怎么问?

与普通 pointermove 的最后坐标有什么区别?

普通事件给一个合并后的公开位置,细分样本补充这次合并期间经过的中间位置。

可以用于鼠标吗?

它属于 Pointer Events,鼠标也可产生指针事件;高采样手写笔场景通常更能体现收益。

怎样避免处理太多点卡顿?

可缓存点、按帧批量绘制,并只在绘图状态下读取样本。

从一道题,走向一组知识

把知识连起来

事件系统

怎样拦截 contextmenu 并显示自己的右键菜单?

右键菜单定位只需当前坐标;绘图笔迹才需要从 getCoalescedEvents() 读取合并样本。

事件系统

CustomEvent 的 detail 怎样给组件传数据?

CustomEvent.detail 传业务数据,不提供硬件指针采样。

参考资料

  • MDN 参考文档

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 手写笔快速划线为何会断角
  3. 帧率与采样精度不是同一指标
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑