【问题标题】:How to prevent mousemove after mousedown or mouseup in Chrome [possible bug in Chrome]?如何在 Chrome 中的 mousedown 或 mouseup 后防止 mousemove [Chrome 中的可能错误]?
【发布时间】:2015-05-11 13:53:09
【问题描述】:

使用最新的 Chrome,我注意到事件 mousemovemousedownmouseup 之后触发,即使 鼠标位于同一位置

我有这种奇怪的行为,在 document.documentElement 上附加了一个事件侦听器。

最新的 Firefox 上的相同脚本运行良好,问题似乎只在 Chrome 上。

  • 为什么会触发此事件?
  • 有没有合理的解决办法?

http://jsbin.com/cefoteleqo/1/

document.documentElement.addEventListener('mousedown', function(event){
    console.log('mousedown', event.pageX, event.pageY);  
}.bind(this));
document.documentElement.addEventListener('mouseup', function(event){
    console.log('mouseup', event.pageX, event.pageY);  
}.bind(this));
document.documentElement.addEventListener('mousemove', function(event){
    console.log('mousemove <<<<', event.pageX, event.pageY);  
}.bind(this));

问题出现在 Win 8.1 上:

  • Chrome 版本 42.0.2311.135 m

  • Chrome 版本 44.0.2398.0 金丝雀(64 位)

【问题讨论】:

  • 我无法复制(OSX Yosemite 上的 Chrome 42.0.2311.135(64 位)) - 我可以得到 mousedownmouseup 而没有 mousemove
  • 我在 Win 8.1 上使用 Chrome 版本 42.0.2311.135 m
  • 我遇到了同样的问题,chrome 版本 42.0.2311.135 m - w8.1

标签: javascript html google-chrome


【解决方案1】:

我注意到mousemove 会同时或在mousedown pr mouseup 被触发后的很短的距离(10 毫秒)内触发。

因此,一种可能的工作是在mousemove 上使用event.timeStamp 进行比较。

以下脚本检查 mousemove 事件是否“很快”触发并相应地在控制台中打印结果。

另一种可能的解决方案是在执行 cb for mousemove 时检查鼠标的位置。

这两种解决方案都只是解决这个Chrome Bug.

基于时间戳的解决方案:

http://jsbin.com/jedotomoxu/1/

基于鼠标位置的解决方案:

http://jsbin.com/dinororaju/1/

<script>
    var timeDownUp = null;
    function start() {
        document.documentElement.addEventListener('mousedown', function (event) {
            timeDownUp = new Date().getTime();
            console.log('mousedown', event.pageX, event.pageY, event.timeStamp);
        }.bind(this));
        document.documentElement.addEventListener('mouseup', function (event) {
            timeDownUp = new Date().getTime();
            console.log('mouseup', event.pageX, event.pageY, event.timeStamp);
        }.bind(this));
        document.documentElement.addEventListener('mousemove', function (event) {
            var timeMove = new Date().getTime();
            timeDownUp += 10;
            if (timeMove > timeDownUp) {
                console.log('mousemove', event.pageX, event.pageY, event.timeStamp);
                if (event.which === 1) {
                    console.log('mousemove DRAG', event.pageX, event.pageY, event.timeStamp);
                }
            } else {
                timeDownUp = null;
            }
        }.bind(this));
    }
</script>

【讨论】:

  • 基于鼠标位置的解决方案是否适用于所有情况?如果鼠标沿对角线移动,新的 X+Y 坐标可能会匹配旧的 X+Y 坐标。
  • 基于时间戳的解决方案:工作.. 基于鼠标位置的解决方案:不工作
【解决方案2】:

我也遇到过这个问题。上面的解决方案对我来说有点太多了。我不确定我的解决方案是否适用于所有浏览器,但我可以确认它在我当前运行的 chrome 版本中有效:版本 48.0.2564.109 m

svg.element.addEventListener('mousemove', mouseMoved);
svg.element.addEventListener('mousedown', mouseDown);

var mouseDownTriggered = false;

function mouseDown(evt)
{
    console.log('mouse down');
    mouseDownTriggered = true;
}

function mouseMoved(evt)
{
    if (mouseDownTriggered)
    {
        mouseDownTriggered = false
    }
    else
    {
        console.log('mouse moved');
    }
}

我注意到当您按下鼠标时,顺序始终是鼠标(向下 -> 向上 -> 移动)。 所以我只是标记鼠标并让鼠标移动来吸收呼叫。

【讨论】:

  • 这种方法存在一些问题。首先,在我的 Chrome 版本 (54.0.2840.99 m) 中,它只会触发 mouseMove 事件每隔一次右键单击。另一个问题是这种行为在其他浏览器中不会发生。因此,在其他浏览器中使用这种方法,并且每隔一次右键单击,第一个合法的 mousemove 事件将不会被触发。对于某些实现,这可能不是问题。
猜你喜欢
  • 2013-07-02
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多