Chrome鼠标按下和松开事件不再起作用,其他浏览器正常。

17

截至今天(或昨天,当时没有注意到),mousedown和mouseup事件不再起作用。我使用的是Chrome版本55.0.2883.95(64位)。Safari和FireFox工作正常(我在mac电脑上)。

以下是代码:

document.getElementById("floorplan-backdrop-rect").addEventListener('mousedown', function(ev) {
    o.clickDown(ev);
}, false);

document.getElementById("floorplan-backdrop-rect").addEventListener('mouseup', function(ev) {
    o.clickUp(ev);
}, false);

我们是否错过了关于鼠标事件的任何 API 更改?注册这些事件时,Chrome 也没有抛出任何警告。触摸按下和触摸释放事件在开发者工具中模拟 iPad 模式时似乎也失败了。

编辑:切换选项卡后或调整窗口大小后,这些事件似乎会短暂地传递。然后它们再次停止...

问候


2
我正在使用Chrome 88,他们肯定没有删除onmousedown和onmouseup。这将是一个非常愚蠢的举动,因为它会破坏大量网站。最好的猜测是这个版本的Chrome中存在一个错误。 - user2867288
2个回答

22

编辑(查看下面的旧答案):

Chrome从55版本开始放弃了鼠标事件,转而采用指针事件。

为什么(W3C):

今天,大多数[HTML5]内容都是使用和/或设计用于鼠标输入的。那些以自定义方式处理输入的人通常编写[DOM-LEVEL-3-EVENTS] Mouse Events。然而,今天的新型计算设备包括其他形式的输入,包括触摸屏、笔输入等。已经为处理每种输入形式分别提出了事件类型。但是,当添加对新输入类型的支持时,这种方法通常会产生不必要的逻辑重复和事件处理开销。这往往会在只考虑一种设备类型时创建兼容性问题的内容。此外,为了与现有的基于鼠标的内容兼容,大多数用户代理为所有输入类型触发Mouse Events。这使得不清楚一个Mouse Event是否代表实际的鼠标设备或是否因兼容性而来自另一种输入类型,这使得同时编写两种设备类型变得困难。

可用代码:

要为“相同”事件添加不同的事件侦听器,请使用以下代码:

// Put these in seperate function instead of anonymous ones
// since you will need them later to deregister the event
function onPointerDown(event){ /** Do stuff here **/ }
function onPointerHover(event){ /** Do stuff here **/ }
function onPointerMove(event){ /** Do stuff here **/ }
function onPointerUp(event){ /** Do stuff here **/ }

// Add event listeners
if (isEventSupported("onpointerdown")) {
    domElement.addEventListener("pointerdown", onPointerDown, false);
    domElement.addEventListener("pointermove", onPointerHover, false);
    domElement.addEventListener("pointermove", onPointerMove, false);
    domElement.addEventListener("pointerup", onPointerUp, false);
} else if (isEventSupported("ontouchstart")) {
    domElement.addEventListener("touchstart", onPointerDown, false);
    domElement.addEventListener("touchmove", onPointerHover, false);
    domElement.addEventListener("touchmove", onPointerMove, false);
    domElement.addEventListener("touchend", onPointerUp, false);
} else if (isEventSupported("onmousedown")) {
    domElement.addEventListener("mousedown", onPointerDown, false);
    domElement.addEventListener("mousemove", onPointerHover, false);
    domElement.addEventListener("mousemove", onPointerMove, false);
    domElement.addEventListener("mouseup", onPointerUp, false);
}

// Remove event listeners
if (isEventSupported("onpointerdown")) {
    domElement.removeEventListener("pointerdown", onPointerDown, false);
    domElement.removeEventListener("pointermove", onPointerHover, false);
    domElement.removeEventListener("pointermove", onPointerMove, false);
    domElement.removeEventListener("pointerup", onPointerUp, false);
} else if (isEventSupported("ontouchstart")) {
    domElement.removeEventListener("touchstart", onPointerDown, false);
    domElement.removeEventListener("touchmove", onPointerHover, false);
    domElement.removeEventListener("touchmove", onPointerMove, false);
    domElement.removeEventListener("touchend", onPointerUp, false);
} else if (isEventSupported("onmousedown")) {
    domElement.removeEventListener("mousedown", onPointerDown, false);
    domElement.removeEventListener("mousemove", onPointerHover, false);
    domElement.removeEventListener("mousemove", onPointerMove, false);
    domElement.removeEventListener("mouseup", onPointerUp, false);
}

参考资料:


旧答案:


看起来 Chrome 在 55 及以上版本中放弃了鼠标事件,转而使用指针事件。

将原始代码更改为以下内容可以解决我们在 Chrome 中的问题:

注意:不建议使用此方法,因为我们无法像下面的新示例那样取消注册侦听器。

document.getElementById("some-id").addEventListener('pointerdown', function(ev) {
    o.clickDown(ev);
}, false);

document.getElementById("some-id").addEventListener('pointerup', function(ev) {
    o.clickUp(ev);
}, false);
请注意,如果您对事件类型进行了其他检查,就像我们一样,那么类型也会从'mouseup'更改为'pointerup',从'mousedown'更改为'pointerdown'。有关更新文章的详细信息,请参阅此处。 https://developers.google.com/web/updates/2016/10/pointer-events

通过添加mousedown、pointerdown和touchstart,这个函数会被调用2-3次,是吗? 例如,在该函数中我们增加一个数字,那么在这种情况下它将被增加超过我们想要的数量。 如果是这样,怎么做才能防止其他调用呢? - Saragani
我认为浏览器已经覆盖了这个问题,但为了确保,您可以使用示例中的更新代码! - Wouter Coebergh
1
好的,我已经在HTML中测试过了(而不是在JavaScript中),结果如下: <Button onmousedown='someFunc()' ontouchstart='someFunc() onpointerdown='someFunc()>Click<Button/>在Chrome桌面上调用了2次函数,在手机上调用了3次函数(可能是因为触摸事件在手机上多了一个)。所以我认为从JavaScript中注册事件不会改变任何事情。感谢您提供更新的代码。 - Saragani
为什么要移除事件监听器? - Choylton B. Higginbottom
什么是isEventSupported()?它不是DOM方法,也没有在这里定义。 - user1009908
不,没有被放弃的东西 - 鼠标事件在所有主要浏览器(包括 Chrome)中仍在2022年触发。 - Oktokolo

2

补充@WouterCoebergh的解决方案。您必须记得为旧事件添加备用方案。可以通过以下方式完成,取自同一[1]源。

var mousedownEvent = function(ev) {
  o.clickDown(ev);
}

var elm = document.getElementById("floorplan-backdrop-rect");

if (window.PointerEvent) {
  elm.addEventListener('pointerdown', mousedownEvent);
} else {
  elm.addEventListener('mousedown', mousedownEvent);
}

[1]: Google Developers Blog


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接