clearTimeout не работает для события mouseup - PullRequest
0 голосов
/ 14 октября 2019

Почему тайм-аут не сбрасывается в этой настройке? Как я могу выполнить make (), чтобы остановить выполнение отложенных действий?

var active = false;
var delay;

window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);

function down(e) {
    active = true;
    console.log("down")
    window.scrollTo(0,document.body.scrollHeight);
}

function up(e) {
    active = false;
    clearTimeout(delay); //expecting this to clear delay
    console.log("up")
    window.scrollTo(0,document.body.scrollHeight);
}

function move(e) {
    if (active) {
        delay = setTimeout(function() {
            console.log("move")
            window.scrollTo(0,document.body.scrollHeight);
        }, 50);
    }
}

Ожидается очистка задержки при наведении мыши, но она все еще выполняется.

Ответы [ 3 ]

0 голосов
/ 15 октября 2019

Ответ:

В вашем коде есть несколько параметров, которые нужно настроить:

  • Вместо постоянного переназначения delay с новым Timeout таймером, просто используйте Interval.
  • Вы должны установить таймер только в том случае, если состояние активно И задержка еще не существует. это останавливает несколько Таймеров от существующих

Есть несколько вещей, которые нужно отрегулировать и понять о Таймерах в JavaScript:

  • Когда вы устанавливаете Таймер,переменная, в которой находится таймер, настроена на возврат целого числа. Это идентификатор таймера в текущей области.
  • Когда вы сбрасываете таймер, переменная не сбрасывается в undefined - она ​​остается той же самой Integer / ID. Это потому, что вы не очищаете переменную, область действия останавливает Таймер , который соответствует идентификатору переменной дома.
  • Из-за вышеизложенного вы должны явно установить переменную, в которой находится таймер, на undefined (или другое значение falsy) после , очистив его для проверки существования.

var active = false;
var delay;

window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);

function down(e) {
    active = true;
    console.log("down")
    window.scrollTo(0,document.body.scrollHeight);
}

function up(e) {
    active = false;
    clearTimeout(delay); //expecting this to clear delay
    delay = undefined;
    console.log("up")
    window.scrollTo(0,document.body.scrollHeight);
}

function move(e) {
    if (active) {
      if(!delay) {
        delay = setInterval(function() {
            console.log("move")
            window.scrollTo(0,document.body.scrollHeight);
        }, 50);
      }
    }
  else { //fallback in case of Browser Queuing issues
   if(delay) { 
     clearTimeout(delay);
     delay = undefined;
   }
  }
}

Отредактировано

Из-за комментариев с проблемами я добавил откат в mousemove , который удалит таймересли состояние неактивно, но delay все еще определено. Я не верю, что вам это технически необходимо, но на практике очереди событий браузера и таймеры иногда не ладят, как ожидалось.

0 голосов
/ 20 октября 2019

Итак, я узнал из ответов, что setTimeout создает новый независимый таймер каждый раз, когда move() выполняется. Насколько я понимаю, каждый новый таймер перезаписывает предыдущий, но поскольку это не тот случай, я должен был думать о чем-то другом.

Я действительно не объяснил, что мне действительно нужно было достичь с задержкой, поэтому позвольте мнеуточнить. Я хочу создать тайм-аут для действия, если это действие не было выполнено в течение x времени. Использование setTimeout в действии само по себе создало проблему, заключающуюся в том, что в действии потенциально может быть несколько выполнений в очереди, ожидающих выполнения даже после событий mouseup.

Поэтому вместо этого я использовал setTimeout для новой переменной, которая действует как блокировка длядействие. В результате получается следующий код:

var active = false;
var actionTimeout = false;
var actionTimeStamp;
var actionLock = false;

window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);

function down(e) {
    active = true;
    console.log("down")
    window.scrollTo(0,document.body.scrollHeight);
}

function up(e) {
    active = false;
    console.log("up")
    window.scrollTo(0,document.body.scrollHeight);
}

function move(e) {
    if (active) {
        if ((Date.now() - actionTimeStamp > 500) && (!actionTimeout)) { // get time elapsed and compare to threshold (500ms)
            actionTimeout = true; //this is for the if statement above to prevent multiple timeouts
            actionLock = false; // set the lock
            setTimeout(function() { // remove lock after 50ms
                actionTimeout = false;
                actionLock = true;
                actionTimeStamp = Date.now(); // timestamp here to make sure we don't lock again to soon. (helps if setTimeout is => than threshold.
            }, 50);
        }
        if (actionLock) { //do our action
            console.log("move")
            window.scrollTo(0,document.body.scrollHeight);
            actionTimeStamp = Date.now();  // timestamp last execution
        }
    }
}

Спасибо всем за участие в комментариях и ответах. Очень ценят.

0 голосов
/ 15 октября 2019

Вы продолжаете делать тайм-ауты на каждом движении. Он не заменяет последний ...

Ваш код в основном такой:

delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- cancels this one
window.clearTimeout(delay)

Поэтому вам нужно удалить его перед созданием нового

if (active) {
    if (delay) window.clearTimeout(delay)
    delay = setTimeout(function() {
        console.log("move")
        window.scrollTo(0,document.body.scrollHeight);
    }, 50);
}

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

...