Javascript нажмите и удерживайте элемент с помощью setTimeout - PullRequest
1 голос
/ 27 июля 2011

Мне нужно иметь некоторые функциональные возможности в моем веб-приложении, где определенное действие происходит, когда пользователь нажимает и удерживает элемент. Думайте об этом как о долгом нажатии на Android.

У меня есть мой div:

<div id="myDiv"
  onmousedown="press()"
  onmouseup="cancel()"
  onmouseout="cancel()"
  onmousemove="cancel()">Long Click Me</div>

и мой JavaScript:

var down = false;

function press()
{
  down = true;
  setTimeout(function() { action(); }, 1500);
}

function cancel()
{
  down = false; // this doesn't happen when user moves off div while holding mouse down!
}

function action()
{
  if (!down)
    return; // if the flag is FALSE then do nothing.

  alert("Success!");
  down = false;
}

Это работает, пока все, что я делаю, это нажимаю и удерживаю элемент. У меня есть события onmouseout и onmousemove для вызова cancel (), потому что я хочу, чтобы у пользователя была возможность изменить свое мнение и убрать мышь с элемента перед началом действия ().

К сожалению, мой код этого не делает. На самом деле, если пользователь нажимает на мгновение вниз, убирает мышь с div и отпускает до через 1,5 секунды, тогда action () не вылетит, как ожидалось.

Редактировать : Спасибо всем за ваш вклад, но оказывается, я просто немного особый и не увидел, что я забыл заглавную букву в своем HTML в моем onmouseout. Пример кода, который я привел выше, должен работать точно так, как ожидалось.

Ответы [ 4 ]

0 голосов
/ 27 июля 2011

Есть несколько вещей, которые не так с вашим кодом, как я вижу.

Первый

bool down = false;

не является допустимым JavaScript. Должно быть

var down = false;

Тогда у вас есть две переменные с именем down: логическое значение и функция. Функция будет перезаписывать переменную до тех пор, пока вы не выполните одно из утверждений, которое устанавливает down в true или false.

Как уже говорили другие: после установки отложенная функция продолжит выполняться через 1,5 секунды, если вы не отмените тайм-аут. Но опять же, это не имеет значения, так как вы проверяете, нажата ли кнопка мыши, прежде чем что-либо делать.

Так что я бы сказал, переименуйте логическую переменную в isMouseDown или что-то еще и попробуйте снова.

0 голосов
/ 27 июля 2011

Вам также необходимо очистить тайм-аут в вашей функции отмены - в противном случае он все равно будет срабатывать - как вы его инициировали в функции отключения.

так ..

bool down = false;
//your timeout var
var t;

function down()
{
  down = true;
  t = setTimeout(function() { action(); }, 1500);
}

function cancel()
{
  down = false;
clearTimeout(t);
}

function action()
{
  if (!down)
    return;

  alert("Success!");
  down = false;
}
0 голосов
/ 27 июля 2011

для отмены тайм-аута в функции cancel (), используйте

var mytimer = null;

function ondown(){mytimer = setTimeOut('action()', 1500;)}   

function cancel(){clearTimeout(mytimer);}
function action(){mytimer=null; alert('success!');}

и обратите внимание, что вы использовали down сначала как переменную end, а затем как функцию ... Вызов if(!down) всегда будетвернуть false, потому что down относится к функции.

0 голосов
/ 27 июля 2011

Конечно, action () все еще вызывается. Вы на самом деле не отменили функцию setTimeout(). Я подозреваю, что, возможно, в вашем реальном коде у вас есть проблема с областью видимости, и, возможно, вы не тестируете ту версию переменной done, которая, как вы думаете, является.

Лучше, чем использование флага down, - отслеживать возвращаемое значение с setTimeout() и фактически отменять таймер в функции cancel(). Тогда action() никогда не сработает, если вы этого не хотите. Я думаю, что это технически более правильное поведение, когда вы мышите, чтобы отменить любой шанс срабатывания таймера.

Также нет такой вещи как:

bool down = false;

в JavaScript. Это должно быть:

var down = false;

Я бы порекомендовал этот код:

var downTimer = null;

function down()
{
  cancel();
  downTimer = setTimeout(function() { action(); }, 1500);
}

function cancel()
{
  if (downTimer) 
  {
    clearTimeout(downTimer);
    downTimer = null;
  }
}

function action()
{
  downTimer = null;
  alert("Success!");
}
...