jQuery:处理多个事件以获得最佳性能的最佳方式

时间:2013-06-21 07:00:17

标签: jquery performance events jquery-on

如果我需要使用jQuery .on()多个事件附加到同一个元素,我应该将所有事件合并到一个调用中并使用event.type区分它们吗?或者我应该为每个事件单独.on()召唤?

合并事件:

$('#main').on('mouseenter mouseleave click', '.myElement', function(event) {
    if (event.type == 'click') {
       return false;

    } else if (event.type == 'mouseenter') {
        $(this).addClass('active');

    } else if (event.type == 'mouseleave') {
        $(this).removeClass('active');
    }
}

单独的活动:

$('#main').on('click', '.myElement', function(event) {
   return false;
}

$('#main').on('mouseenter', '.myElement', function(event) {
    $(this).addClass('active');
}

$('#main').on('mouseleave', '.myElement', function(event) {
    $(this).removeClass('active');
}

哪一个最快?

[编辑]其他详细信息:显然我们需要考虑两个方面,第一个是页面加载完毕并且正在设置事件处理程序,显然只使用一个.on()致电。然而,第二个方面是当这些事件实际被触发时,当鼠标悬停或点击.myElement我认为更重要,因为它会多次发生,而.on()调用只会被调用一次(如果DOM发生变化,则更多,但仍然小于事件本身。)

3 个答案:

答案 0 :(得分:4)

您必须区分绑定事件(将回调附加到事件),以及实际处理触发事件(调用/执行回调)之间。第一个可能每页只发生一次,而后者可能会发生一百次,具体取决于用户活动。

  • 如果您只考虑事件绑定 - 这在文档就绪(最终)和每次DOM更改时发生(例如,在Ajax完成时) - 那么只使用一个{{1仅使用一个回调调用的速度更快:http://jsperf.com/multiple-jquery-events/2

  • 如果您考虑处理被触发的事件 - (即用户点击或鼠标悬停.on()) - 然后将所有事件合并为一个回调并区分它们使用.myElement语句也比拥有多个回调更快:http://jsperf.com/multiple-jquery-events/4

以下是两项测试的综合结果:

绑定速度最快,处理事件的速度最快

if

以上代码是推荐的语法。以下示例仅供参考。


绑定约慢30%,处理事件的速度减慢50%:

$('#main').on('mouseenter mouseleave click', '.myElement', function(event) {

    // Processing of the triggered event:
    if (event.type == 'click') {
        return false;

    } else if (event.type == 'mouseenter') {
        $(this).addClass('active');

    } else if (event.type == 'mouseleave') {
        $(this).removeClass('active');
    }
});

绑定最慢,处理事件的速度减慢70%:

$('#main').on('click', '.myElement', function(event) {
    return false;
});

$('#main').on('mouseenter', '.myElement', function(event) {
    $(this).addClass('active');
});

$('#main').on('mouseleave', '.myElement', function(event) {
    $(this).removeClass('active');
});

绑定速度慢约25%,处理事件的速度最慢:

$('#main').on({
    mouseenter: function() {
        $(this).addClass('active');
    },
    mouseleave: function() {
        $(this).removeClass('active');
    },
    click: function() {
        return false;
    }
}, '.myElement');

绑定约慢20%,处理事件的速度减慢60%:

$('#main').on('click', '.myElement', function(event) {
    return false;
});

$('#main').on('hover', '.myElement', function(event) {
    $(this).addClass('active');
}, function() {
    $(this).removeClass('active');
});

答案 1 :(得分:0)

我认为combined事件会比seperated快。 因为在combined中使用jquery.on() jquery library一次调用时,它会在内部调用它。如果它被称为seperately,则每次需要调用jquery library时。  如果您看到代码,那么您会找到,

 on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
    var type, origFn;

    // Types can be a map of types/handlers
    if ( typeof types === "object" ) {
        // ( types-Object, selector, data )
        if ( typeof selector !== "string" ) {
            // ( types-Object, data )
            data = data || selector;
            selector = undefined;
        }
             /* here is looping if in case combined event then this
                loop will work and all your events will bound here */
             /* in case of seperated events
                loop will work only for selected event and it will bind*/
        for ( type in types ) {
            this.on( type, selector, data, types[ type ], one );
        }
        return this;
    }

如果您使用combined events喜欢

,则会更容易
$('#main').on({
    mouseenter: function() {
        $(this).addClass('active');
    },
    mouseleave: function() {
        $(this).removeClass('active');
    },
    click: function() {
        return false;
    }
}, '.myElement');

答案 2 :(得分:-1)

正如预期的那样,只有一个选择器的选择器最快。请亲自查看测试结果:

http://jsperf.com/multiple-jquery-events

我还添加了一些其他代码片段来做同样的事情。这段代码最好用:

$('#main').on('mouseenter mouseleave click', '.myElement', function(event) {
    if (event.type == 'click') {
        return false;
    } else if (event.type == 'mouseenter') {
        $(this).addClass('active');
    } else if (event.type == 'mouseleave') {
        $(this).removeClass('active');
    }
});

然而第二个(case-switch)和last(no on())几乎一样快

$('#main .myElement').click(function(event) {
    return false;
}).mouseenter(function(event) {
    $(this).addClass('active');
}).mouseleave(function(event) {
    $(this).removeClass('active');
});