为什么React的onContextMenu在Chrome中对禁用的元素有效?

eimct9ow  于 2023-03-05  发布在  Go
关注(0)|答案(1)|浏览(154)

我发现了一些很奇怪的事情,在所有主流浏览器中,上下文菜单事件对禁用的元素不起作用,所以这不会打印到控制台:

<button
    type="button"
    onContextMenu="console.log(123)"
    disabled
>
    Click me
</button>

但是React有点不同,我尝试通过React组件做同样的事情:

const MyComponent = () => (
    <button
        type="button"
        onContextMenu={() => console.log(123)}
        disabled
    >
        Click me
    </button>
);

这一次,在Chrome浏览器中,它会打印到控制台,但在其他浏览器中却不会。出于教育目的,我试图理解HTML的onContextMenu和React的onContextMenu之间的区别,以及为什么只有Chrome处理它的方式不同。超级奇怪。
Codesandbox中复制

db2dz4w8

db2dz4w81#

我花了一段时间来研究这个问题,它看起来像是Chrome中的一个bug,尽管contextmenuPointerEvent的一种,但它只在冒泡时触发禁用的元素 *。
下面是一个没有React的JSFiddle:https://jsfiddle.net/bpe0yoc6/4/

// Only in chrome does this fire
document.querySelector("#root").addEventListener("contextmenu", (e) => { console.log("contextmenu fired", e.target.tagName) })

document.querySelector("#root").addEventListener("click", (e) => { console.log("click fired", e.target.tagName) })
#root {
  width: 200px;
  height: 200px;
  display: block;
  background-color: #ccc;
}
<div id="root">
  <button
      type="button"
      disabled
  >
      Click me
  </button>
</div>

React在DOM树的根目录注册事件句柄,这就是这样做的原因:

document.querySelector("button").addEventListener("contextmenu", (e) => { ... })

将不会触发禁用按钮,oncontextmenu也不会。
我在Chromium问题跟踪器上打开了一个问题:https://bugs.chromium.org/p/chromium/issues/detail?id=1421370

相关问题