Вызов функции Javascript setTimeout с аргументом события? - PullRequest
9 голосов
/ 30 ноября 2010

Каков наилучший способ получить объект события при использовании setTimeout? Я использую jQuery для нормализации модели событий во всех браузерах, но я не уверен, как получить объект 'e' в функцию checkPos.

Мой текущий код:

function MouseDownEvent(e) {
    *snip*
    timeoutID = setTimeout(checkPos(e), 500);
}
function checkPos(e) {
    //function uses e on a timeout of 500ms
    timeoutID = setTimeout( checkPos(e) }, 500);
}

В настоящее время этот код работает один раз, потому что функция вызывается в событии mousedown, но никогда не обновляет объект e, когда пользователь перемещает мышь. Консоль ошибок JavaScript FF также объявляет, что это «бесполезный вызов setTimeout (пропущены кавычки вокруг аргумента?)», Но следование этому совету приводит к его полному отказу.

Как я могу получить аргумент события 'e' из вызова setTimeout?

Редактировать: добавлено в код, который перезапускает функцию checkPos каждые 500 мс

Ответы [ 4 ]

10 голосов
/ 30 ноября 2010

Попробуйте:

function MouseDownEvent(e) {
    *snip*
    timeoutID = setTimeout(function(){checkPos(e);}, 500);
}
function checkPos(e) {
    //function uses e on a timeout of 500ms
}

РЕДАКТИРОВАТЬ из-за комментариев OP ..

Чтобы иметь доступ к обновленному событию каждый раз при запуске checkPos:

var myNamespace = {};

$('body').mousemove(function(e) {
    myNamespace.mouseEvent = e; 
});

function checkPos() {
    doSomethingWith(myNamespace.mouseEvent);
}

timerID = setInterval(checkPos, 500);
7 голосов
/ 30 ноября 2010

Во-первых, почему вы используете два тайм-аута?Мне кажется, что setInterval () будет лучше

function MouseDownEvent(e) {
 *snip*
 clearInterval(intervalID);
 intervalID = setInterval(function(){checkPos(e);}, 500);
}

Во-вторых, не могли бы вы уточнить это: "... но никогда не обновляет объект e, когда пользователь перемещает мышь"Зачем обновлять объект события, когда пользователь перемещает мышь?Вы только назначили обработчик mouseDown.Если вы хотите что-то делать при каждом перемещении мыши, вам следует использовать событие mouseMove, в этом случае тайм-аут / интервал в любом случае будет ненужным.Решение в первую очередь и использовать синхронизированные обработчики, когда вам абсолютно необходимо.

* Редактировать - решение проблем, поднятых в комментариях *

var handler = {
    i : 0,
    function : mouseMoveEvent(e) {
      handler.i++;
      if (handler.i % 100 == 0) {
        //Do expensive operations
      }
    }
}

$(myElement).bind("mousemove", handler.mouseMoveEvent);
1 голос
/ 30 ноября 2010

Насколько я мог видеть, IE не позволяет передавать объект "событие" так, как вам нужно.

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

Например: http://jsfiddle.net/YvYtn/1/

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

Код JS:

var _lastPosX= null;
function MouseDownEvent(evt) {
    if (typeof evt == "undefined" || !evt)
        evt = window.event;
    _lastPosX = (evt.clientX || evt.pageX);
    timeoutID = window.setTimeout("checkPos();", 500);
}
function checkPos() {
    alert(_lastPosX);
}
1 голос
/ 30 ноября 2010

Вы можете использовать функцию карри, она есть для jQuery здесь .

Как правило, у вас будет это:

function foo(a, b)
{
    alert(a + b);
}

var bar = curry(foo, 1);

bar(2); // alerts 3, as if you had called foo(1, 2)

чтобы вы могли сделать:

setTimeout(curry(checkPos, e), 500);

Поскольку curry возвращает функцию с первым аргументом, связанным с e, вы можете передать ее прямо в setTimeout.

...