绑定多个事件或将一个事件与交换机绑定是否更有效

时间:2014-07-30 02:04:37

标签: javascript jquery performance event-handling

我有许多事件需要绑定为文档对象的委托,如下所示:

$(document).on('click', '.create-post', Fti.Modals.createPostModal.open);
$(document).on('click', '.flag', Fti.modalHelper.openFlagModal);
$(document).on('click', '.login', Fti.Modals.loginModal.open);
$(document).on('click', '.register', Fti.Modals.registerModal.open);

通过一些创意重构,我做到了这一点:

选项1。

var eventTriggers = [
    {
        element: '.create-post',
        event: Fti.Modals.createPostModal.open
    },{
        element: '.flag',
        event: Fti.modalHelper.openFlagModal
    },{
        element: '.login',
        event: Fti.Modals.loginModal.open
    },{
        element: '.register',
        event: Fti.Modals.registerModal.open
    }
];
for(var i = i, len = eventTriggers.length; i < len; i++){
    $(document).on('click', eventTriggers[i].element, eventTriggers[i].event)
}

我想知道将一个事件绑定到文档对象并根据事件目标执行switch-case是否更好,如下所示:

选项2。

var eventTriggers = [
    {
        element: '.create-post',
        event: Fti.Modals.createPostModal.open
    },{
        element: '.flag',
        event: Fti.modalHelper.openFlagModal
    },{
        element: '.login',
        event: Fti.Modals.loginModal.open
    },{
        element: '.register',
        event: Fti.Modals.registerModal.open
    }
];

var elements = eventTriggers.map(function(item){
    return item.element;
});

$(document).on('click', elements.join(','), function(e){
    var $target = $(e.target)
    for(var i = 0, len = eventTriggers.length; i < len; i++){
        if($target.hasClass(eventTriggers[i].element.substr(1))){
            eventTriggers[i].event.call(e.target);
        }
   }
});

有没有人对哪个选项表现更好有任何建议或经验?

2 个答案:

答案 0 :(得分:0)

使用多个侦听器来提高灵活性。如果你需要分离/删除它,它不会影响其他人。

答案 1 :(得分:0)

根据您的浏览器,性能差异似乎可以忽略不计,约为10%。在webkit浏览器中,添加单个事件监听器似乎需要不到一毫秒(您的四个事件有时会轮到需要1毫秒来连接)。具有100k次迭代的Running this fiddle在i5 CPU上大约需要5到7秒。

除非你一直在做这样的大量事件,否则它似乎是一个过早优化的例子。如果可能,请考虑使用其他ID选择器而不是class选择器,因为这可能会为您节省更多时间。

<a class="create-post">c</a><a class="flag">f</a><a class="login">l</a><a class="register">r</a>
<script>
$(document).ready(function () {
    var iterations = 100000;
    var simple = 0;
    var trigger = 0;
    var eventTriggers = [{
        element: '.create-post',
        event: function () {}
    }, {
        element: '.flag',
        event: function () {}
    }, {
        element: '.login',
        event: function () {}
    }, {
        element: '.register',
        event: function () {}
    }];

    var mt = (new Date).getTime();
    var iteration = 0;
    while (iteration < iterations) {
        $(document).on('click', '.create-post', function () {});
        $(document).on('click', '.flag', function () {});
        $(document).on('click', '.login', function () {});
        $(document).on('click', '.register', function () {});
        iteration++;
    }
    simple = (new Date).getTime() - mt;


    var mt = (new Date).getTime();
    var iteration = 0;
    while (iteration < iterations) {
        for (var i = 0; i < eventTriggers.length; i++) {
            $(document).on('click', eventTriggers[i].element, eventTriggers[i].event);
        }
        iteration++;
    }
    trigger = (new Date).getTime() - mt;

    console.log('simple: ' + simple + 'ms');
    console.log('trigger: ' + trigger + 'ms');
    console.log('diff: ' + (simple - trigger) + 'ms at ' + iterations + ' iterations');
});
</script>