Подтвердить что ты не робот

Как измерить миллисекунды между mousedown и mouseup?

Можно ли измерить количество миллисекунд между нажатием и отпусканием мыши?

4b9b3361

Ответ 1

Вы можете создать закрытие для совместного использования двух переменных: одного для сохранения времени начала и другого для конечного времени, а затем в событии mouseup получить разницу:

(function () {
    var element = document.getElementById('element'),
        start, end;

    element.onmousedown = function () {
      start = +new Date(); // get unix-timestamp in milliseconds
    };


    element.onmouseup = function () {
      end = +new Date();

      var diff = end - start; // time difference in milliseconds
    };

})();

Проверьте этот рабочий пример.

Ответ 2

Обновление в декабре 2017 года: .timeStamp, похоже, теперь корректно реализовано в Chrome, поэтому этот ответ является еще большим улучшением по сравнению с ответом CMS сегодня, чем когда я впервые написал его. Я уточню ответ более тщательно со временем; на данный момент оригинальный ответ - в комплекте с устаревшими утверждениями о том, что он не работает должным образом в Chrome, - сохраняется ниже строки.


tl; dr ответ

  • Получить время между двумя событиями, вычитая свойство .timeStamp первого события из свойства .timeStamp второго события,
  • Никогда не пытайтесь получить время, когда произошло событие, создав new Date() или вызывающий Date.now() внутри своего обработчика.
  • Имейте в виду, что даже если вы будете следовать этому совету, иногда вы можете получать дико неточные ответы в некоторых браузерах, включая Chrome, если выполнение ваших обработчиков задерживается медленным JavaScript, не связанным с вашими обработчиками.

Более длинный ответ

Это гораздо более тонкая проблема, чем другие ответы здесь дают ему честь для бытия.

Подход предложенный ответом CMS - получения времени внутри каждого обработчика путем создания new Date(), а затем вычитания этих времен друг от друга - имеет потенциал для быть грубым неточным. Проблема с этим подходом заключается в том, что вы не сравниваете время, в которое произошли события, вы сравниваете время, в которое их обработчики запускались.

В статье, связанной с вопросом - Джон Ресиг Как работают JavaScript-таймеры - имеет значение для понимания проблемы здесь. Выполнение JavaScript однопоточное, и всякий раз, когда что-то вне JavaScript запускает выполнение JavaScript - будь то тайм-аут, событие или загрузка script, что JavaScript добавляется в очередь обратных вызовов, ожидающих запуска, которые выполняются последовательно. В большинстве браузеров есть один поток JavaScript и одна очередь для каждой вкладки браузера. В Safari существует одна остановка потока, которая разделяется между всеми вкладками - это означает, что медленный JavaScript на одной вкладке может задерживать обработчики событий от запуска на другой вкладке.

Это приводит к двум путям, по которым наша попытка подсчитать время между событиями может быть ужасно привинчена, если мы попытаемся вычислить ее в зависимости от времени, которое выполняют обработчики. Рассмотрим следующие два сценария:

Первый сценарий
  • Выполняется несколько дорогостоящих JavaScript с вычислительными затратами, которые будут выполняться в течение 1 секунды.
  • Первое событие происходит (т.е. пользователь опускается на целевой элемент)
  • 200 миллисекунд позже, происходит второе событие (то есть пользователь нажимает на целевой элемент).

Что будет дальше? Вычислительный дорогостоящий JavaScript заканчивается, а затем оба обработчика событий срабатывают быстро. Следовательно, если вы синхронизируете события, получая текущее время при срабатывании обработчика, вы ошибочно вычисляете время между событиями, которое должно быть близко к 0 миллисекундам.

Второй сценарий
  • Первое событие происходит, и его обработчик срабатывает. Он сохраняет текущее время в переменной для последующей ссылки, а затем начинает выполнять некоторые вычисления, для завершения которых потребуется 1 секунда.
  • 200 миллисекунд после запуска первого события, запускается второе событие.

Что будет дальше? На этот раз, конечно, мы ошибочно вычислим время между событиями как приблизительно 1 секунду, потому что выполнение второго обработчика задерживается.

Это можно увидеть в действии http://jsfiddle.net/gagLxrsc/. Просто нажмите кнопку и обратите внимание, что расчетная разница во времени между mousedown и mouseup всегда составляет примерно 1000 мс.

Что мы можем сделать, чтобы остановить это? Ну, в идеале, нам нужен способ получения фактического времени, когда произошло событие, а не просто время его увольнения. Предлагает ли DOM API нам такую ​​вещь?

Может быть. Это зависит от вашего браузера. События имеют свойство .timeStamp, которое, по мнению некоторых людей, интерпретирует спецификацию, должно предоставить время, когда произошло событие, а не время обработчик уволен. Однако в настоящее время это не достоверно верно во всех браузерах.

В Firefox свойство .timeStamp работает так, как мы этого хотим, - оно дает отметку времени, когда произошло событие mousedown или mouseup, а не когда начался его обработчик. Однако в Chrome свойство .timeStamp дает нам время, в которое ушел обработчик. Существует открытая ошибка в описании отслеживания ошибок, описывающая это поведение, в комплекте с утверждением о том, что поведение Chrome нарушает спецификацию, но никто не предпринял никаких действий так как он был открыт более 2 лет назад.

Для браузеров, таких как Chrome, вы ничего не можете сделать, чтобы гарантировать правильность расхождений во времени, которые вы вычисляете между событиями, потому что у вас просто нет доступа к какой-либо достоверной информации о том, когда произошло событие. Возможно, вы сможете уменьшить потенциальную неточность, избегая когда-либо выполняющих дорогостоящие задачи, зависящие от вычислительных ресурсов, которые блокируют поток JavaScript - действительно, попытка сделать это - хорошая идея, так или иначе, чтобы обеспечить постоянный и отзывчивый интерфейс пользователя и не отставать когда пользователь нажимает кнопку. Но если вы терпите неудачу, или если вы пишете библиотеку или код плагина и не знаете, будет ли другой код JavaScript на странице делать что-то длинное и дорогое, то риск неточности неизбежен - вам просто придется терпеть до тех пор, пока все браузеры не реализуют свойство timeStamp так, как это делает Firefox. Вы по-прежнему могли бы использовать .timeStamp вместо new Date(), хотя, чтобы получить более точные результаты в браузерах, которые действительно реализуют .timeStamp правильно.

Рекомендации и примеры

http://jsfiddle.net/gagLxrsc - это скрипка, которая вычисляет время между a mousedown и mouseup на кнопке, создавая new Date() внутри обработчиков событий. Первый обработчик горячий спит в течение секунды после этого, задерживая второй обработчик от стрельбы. Как в Chrome, так и в Firefox, расчетная продолжительность клика будет примерно на секунду (т.е. Будет неправильной).

http://jsfiddle.net/gagLxrsc/1/ - это модифицированная версия скрипта. Единственное изменение заключается в том, что время, в которое произошли события, определяется с использованием свойства события .timeStamp. В Firefox эта скрипка точно вычисляет длительность щелчка, но в Chrome все еще не так.

Ответ 3

Так как другие ссылки, кажется, сейчас сломаны, по крайней мере на хром, вот простая рабочая демонстрация:

var startTime;

window.startTimer = function() {
    startTime = new Date();
}
window.reportTime = function() {
	alert(new Date() - startTime)
}
<button onmousedown="startTimer()" onmouseup="reportTime()">Measure click time</button>

Ответ 4

Когда onmousedown уволен, вы можете повесить событие onmouseup в окне. Это позволит избежать ненужных замыканий.

el.onmousedown = function () {
  var time = new Date(); //time in milliseconds
  window.onmouseup=function(){
    var diff=new Date()-time;
    window.onmouseup=null;
  }
};

проверьте результат здесь: http://jsbin.com/uneqo

Ответ 5

Вы можете использовать две глобальные переменные для записи времени mousedown и mouseup и иметь вычитание