Как я могу уменьшить замедление от события mousemove?

Я запускаю относительно простую функцию (обновление span innerHTML) на mousemove. Приложение представляет собой карту Leaflet. При движении мыши ощущается ощутимая задержка при масштабировании, панорамировании и загрузке тайлов. Мне нужно обновлять span максимум 10-20 раз в секунду. (См. здесь для соответствующей страницы; обновление касается индикатора X/Z в верхнем правый угол.)

Как лучше всего задержать и/или отложить вызовы событий mousemove? Достаточно ли пропустить обновление innerHTML? Могу ли я отменить регистрацию и повторно зарегистрировать событие после тайм-аута?


person Henry Merriam    schedule 11.01.2012    source источник


Ответы (2)


Попросите mousemove установить строку innerHTML в переменную, а также используйте прямое обычное событие DOM mousemove для элемента, если это возможно. См. http://bugs.jquery.com/ticket/4398.

!function () {
    var buffer = null;

    elem.onmousemove = function () {
        buffer = value;
    };

    !function k() {
        if (buffer) {
            span.innerHTML = buffer;
            buffer = null;
        }
        setTimeout(k, 100);
    }();

}();

Теперь событие mousemove почти не работает (установка innerHTML — это МНОГО работы, кстати), а диапазон обновляется 10 раз в секунду.

person Esailija    schedule 11.01.2012
comment
Спасибо! Я использую Leaflet L.Map.on() для привязки события, и он не использует jQuery, поэтому я думаю, что он уже использует событие DOM. Будет ли синхронизация проблемой с этим методом, или Javascript позаботится об этом достаточно хорошо? Что делает ! перед function k()? - person Henry Merriam; 11.01.2012
comment
@HenryMerriam, выполняющий function k(){}(), является синтаксической ошибкой, потому что он анализируется как объявление функции, а !function k(){}() анализируется как выражение, поэтому оно работает. Я почти уверен, что map.on использует jQuery за кулисами. - person Esailija; 11.01.2012
comment
Nvm Я просмотрел источник, и они используют свою собственную реализацию событий, так что я думаю, это нормально. - person Esailija; 11.01.2012

Изменение текстового узла диапазона будет намного эффективнее, чем изменение innerHTML.

function mouseMoveAction(ev) {
    span.firstChild.data = new Date.toString();
}

Но если текстовые узлы не соответствуют требованиям, и вам нужен innerHTML при перемещении мыши, вы можете указать пороговое значение в обработчике перемещения мыши.

/* Keep CPUs to a minimum. */
var MOUSE_MOVE_THRESHOLD = 25,
    lastMouseMoveTime = -1;

function mousemoveCallback(ev) {
        var now = +new Date;
        if(now - lastMouseMoveTime < MOUSE_MOVE_THRESHOLD)
            return;
        lastMouseMoveTime = now;
        mouseMoveAction(ev);
}

Избегайте jQuery и др.; они напрасно делают вещи намного медленнее и добавляют намного больше сложности.

person Garrett    schedule 11.01.2012