0

我有点用这样的对象来模拟 Backbone 的事件系统:

var events = {
    'click .one': 'fnOne',
    'click .two': 'fnTwo',
    'click .three': 'fnThree'
}

然后使用 jquery 设置事件侦听器,我使用以下内容:

var method,
    match,
    event_name,
    selector;

var scope = {
     // Complex object literal passed to the event's
     // function for access...
};

var delegateEventSplitter = /^(\S+)\s*(.*)$/;
for (key in events) {
    if (events.hasOwnProperty(key)) {
        method = events[key];
        match = key.match(delegateEventSplitter);
        event_name = match[1];
        selector = match[2];

        $('#element').on(event_name,selector,function(event){ 
            method(event,scope);
        });
     }
}

我遇到的问题是它绑定正确,除了所有事件都会触发最后一个函数fnThree

4

2 回答 2

3

Just a closure/loop problem. A closure only binds lexical names, not the values at the time.

One of my favorite ways to capture values is with:

for (key in events) {
    if (events.hasOwnProperty(key)) {
        method = events[key];
        match = key.match(delegateEventSplitter);
        event_name = match[1];
        selector = match[2];

        with ({method:method})
        {
            $('#element').on(event_name,selector,function(event){ 
               method(event,scope);
            });
        }
    }
}

But this causes some acolytes of Doug Crockford to die of heart attack so you can also do:

            (function(method) { $('#element').on(event_name,selector,function(event){ 
               method(event,scope);
            }); })(method);

I'll let you decide which you find preferable.

于 2013-01-30T22:36:37.687 回答
1

尝试使用$.each(). 它的函数参数在每次迭代时方便地形成一个闭包。

$.each(events, function(key, method) {
    var match = key.match(delegateEventSplitter);
    $('#element').on(match[1], match[2], function(event){ 
        method(event, scope);
    });
});
于 2013-01-30T22:37:26.190 回答