Как предотвратить mousemove после mousedown или mouseup в Chrome [возможная ошибка в Chrome]?

Используя последний Chrome, я заметил, что событие mousemove срабатывает после mousedown или mouseup, даже если мышь остается в той же позиции.

У меня есть это странное поведение, связанное с прослушивателем событий на document.documentElement.

Тот же script на последнем 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-разрядная версия)

Ответы

Ответ 1

Я заметил, что огонь mousemove срабатывает одновременно или на очень коротком расстоянии (10 миллисекунд) после mousedown pr mouseup.

Таким образом, возможная работа заключается в использовании event.timeStamp для mousemove для сравнения.

Следующий script проверить, если событие mousemove запущено "в ближайшее время" и соответственно распечатать результат в консоли.

Другим возможным решением может быть проверка положения мыши, когда выполняется cb для mousemove.

Оба решения - это всего лишь работа с этим Ошибка Chrome.

Решение на основе timeStamp:

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>

Ответ 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');
    }
}

Я заметил, что при выводе мыши приказ - это всегда мышь (вниз → вверх → перемещена). Поэтому я просто помещаю мышь вниз, и движение мыши поглощает вызов.