Объявление переменных в событии "mousemove" в jQuery

mousemove-event в jQuery срабатывает каждый раз, когда движется мышь, и это может привести к сотням событий в секунду. Допустим, у нас есть этот фрагмент кода.

$(document).on('mousemove', function(e){

    /**
    *    This piece of code checks if the mouse is within a 50px range 
    *    on either side of the middle of the page. 
    *    If is, it shows a set of elements (contained in the action_dots variable).
    */

    var treshold = 50;
    var action_dots = $('.branch[open][focus]').children('.branch-line').children('.action-dot');
    var opacity = action_dots.css('opacity');

    if(e.pageX >= ($(window).width()/2 - treshold) && e.pageX <= ($(window).width()/2 + treshold)){
        if(opacity == 0){
            action_dots.transition({ opacity: 1 }, 100);
        }
    }
    else{
        if(opacity == 1){
            action_dots.transition({ opacity: 0 }, 100);
        }
    }
});

Эффективно ли объявлять эти переменные каждый раз, когда происходит событие? Так как он должен найти все элементы, соответствующие селектору var action_dotsВы могли бы подумать, что это нагрузка на производительность. Или может jQuery как-то кешировать содержимое var action_dots? Те же самые квесты применимы к проверке точек действия opacity css-свойство с var opacity,

2 ответа

Решение

С точки зрения эффективности, нет, не очень эффективно запускать этот код для каждого пикселя, который перемещает мышь. Что вы можете сделать, это запустить этот код после того, как мышь перестала двигаться для x милисекунд. Что-то вроде этого:

var mouseTimer;
$(document).on('mousemove', function(e) {
    clearTimeout(mouseTimer);
    mouseTimer = setTimeout(function() {    
        var treshold = 50;
        var action_dots = $('.branch[open][focus]').children('.branch-line').children('.action-dot');
        var opacity = action_dots.css('opacity');

        if (e.pageX >= ($(window).width() / 2 - treshold) && e.pageX <= ($(window).width() / 2 + treshold)) {
            if (opacity == 0) {
                action_dots.transition({ opacity: 1 }, 100);
             }
        }
        else {
            if (opacity == 1) {
                action_dots.transition({ opacity: 0 }, 100);
            }
        }
    }, 50); // runs 50ms after mouse movement stops.
});

Согласно моему комментарию: если точки не добавляются динамически, вы просто объявляете action_dots вне $(document).on вызовите, чтобы он заполнялся один раз во время готовности страницы.

$(function(){ // JQuery ready - modern version

    var action_dots = $('.branch[open][focus]').children('.branch-line').children('.action-dot');

    $(document).on('mousemove', function(e){

        /**
        *    This piece of code checks if the mouse is within a 50px range 
        *    on either side of the middle of the page. 
        *    If is, it shows a set of elements (contained in the action_dots variable).
        */

        var treshold = 50;
        var opacity = action_dots.css('opacity');

        if(e.pageX >= ($(window).width()/2 - treshold) && e.pageX <= ($(window).width()/2 + treshold)){
            if(opacity == 0){
                action_dots.transition({ opacity: 1 }, 100);
            }
        }
        else{
            if(opacity == 1){
                action_dots.transition({ opacity: 0 }, 100);
            }
        }
    });
});

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

Пожалуйста, опубликуйте весь JS, если вы хотите конкретный пример (только в том случае, если вам не хватает JQuery "готовая оболочка" - не показана).

Другие вопросы по тегам