Chrome 55 中即将推出 auxclick

什么情况下点击不会被计为 click?对于从事复杂界面开发的 Web 开发者来说,这不是一个抽象的哲学问题。如果您要实现自定义鼠标输入行为,请务必牢记用户意图。例如,如果用户使用鼠标中键点击链接,我们就可以合理地假设用户希望打开一个包含该链接内容的新标签页。如果用户中键点击随机界面元素,您可能需要假定这是无意的,并忽略该输入,而主按钮点击应会触发界面响应。

虽然有点麻烦,但您可以通过单个 click 事件监听器来对这些细微的互动进行建模。您必须明确检查 MouseEventbutton 属性,以确定其是否已设置为 0(表示主按钮),而不是任何其他值(1 通常表示中间按钮等)。但并不是很多开发者都会明确检查 button 属性,这导致代码会以相同的方式处理所有 click,无论按下哪个按钮。

从 Chrome 55 开始,系统会针对使用非主要按钮进行的任何点击触发一种名为 auxclick 的新类型 MouseEvent。与此新事件相伴随的是 click 事件的行为发生了相应变化:它只会在按下主鼠标按钮时触发。我们希望这些更改能让 Web 开发者更轻松地编写事件处理脚本,使其仅响应他们关注的点击类型,而无需专门检查 MouseEvent.button 属性。

减少误报

如前所述,创建 auxclick 的一个动机是避免部署会错误地替换“中键点击打开标签页”行为的自定义 click 处理脚本。例如,假设您编写了一个 click 事件处理脚本,该脚本使用 History API 重写了地址栏,并实现了自定义单页导航。可能如下所示:

document.querySelector('#my-link').addEventListener('click', event => {
    event.preventDefault();
    // ...call history.pushState(), use client-side rendering, etc....
});

当由鼠标的主按钮触发时,您的自定义逻辑可能会按预期运行,但如果该代码在点击中间按钮时运行,则实际上是误报。在新行为推出之前,您最终会阻止打开新标签页的默认操作,这与用户的预期相悖。虽然您可以在处理脚本开头明确检查 event.button === 0,并仅在存在该情况时执行代码,但很容易忘记或根本意识不到执行此操作的必要性。

仅运行您需要的代码

减少假正例的另一面是,只有在实际点击了非主鼠标按钮时,auxclick 回调才会运行。例如,如果您的代码需要在打开新标签页之前计算适当的目标网址,您可以监听 auxclick 并在回调中添加该逻辑。它不会在点击鼠标主按钮时产生运行开销。

浏览器支持和兼容性

此新行为目前仅在 Chrome 55 中实现。如初始提案中所述,我们衷心期待网络开发者社区提供反馈(无论是正面还是负面反馈)。若要与负责标准化流程的人员分享反馈,提交 GitHub 问题是最佳方式。

与此同时,开发者无需等待 auxclick 广泛提供,即可遵循一些处理鼠标事件的最佳实践。如果您在 click 事件处理脚本的开头花些时间检查 MouseEvent.button 属性的值,则可以确保采取适当的措施。无论是否支持 auxclick 的原生方式,以下模式都会以不同的方式处理主要点击和辅助点击:

function handlePrimaryClick(event) {
    // ...code to handle the primary button click...
}

function handleAuxClick(event) {
    // ...code to handle the auxiliary button click….
}

document.querySelector('#my-link').addEventListener('click', event => {
    if (event.button === 0) {
    return handlePrimaryClick(event);
    }


    // This provides fallback behavior in browsers without auxclick.
    return handleAuxClick(event);
});

// Explicitly listen for auxclick in browsers that support it.
document.querySelector('#my-link').addEventListener('auxclick', handleAuxClick);