Polmonite
Polmonite

Reputation: 943

JavaScript function to bind events specified in object

I'm creating a function that gets in input a JavaScript object with this format:

var input = {
    'selector1' : {
        'event1'    : function(element,value){
            // ...
        },
        'event2'    : function(element,value){
            // ...
        },
        ...
        'eventN'    : function(element,value){
            // ...
        }
    },
    'selector2' : {
        'event1'    : function(element,value){
            // ...
        },
        'event2'    : function(element,value){
            // ...
        },
        ...
        'eventN'    : function(element,value){
            // ...
        }
    }
}

My function bind the events this way:

function event_binder(events_fns){
    for(sel in events_fns){
        for(ev in events_fns[sel]){
            $(sel).on(ev,function(){
                console.log(sel+'+'+ev);
                var th = $(this);
                var func_to_call = events_fns[sel][ev];
                func_to_call(th,th.html());
            });
        }
    }
}

but when I run it, it shows that every event's been bound to the last event.

I created a jsFiddle for better explain my problem: http://jsfiddle.net/Polmonite/6rRgr/

As the console.log suggest, it seems that the event binding always use the last function in the object. If I'm interpreting right, it would seems that the evaluation of the .on function only happens at the end, so it use the last values of sel and ev variables (a scoping problem), but I don't quite understand how to fix it.

EDIT: I need to specify one thing: I want to create a working version of the event_binder function, not a working version of the jsfiddle, which is just an example.

Upvotes: 0

Views: 78

Answers (1)

pimvdb
pimvdb

Reputation: 154958

The issue is scope - there is only one sel and ev variable in the whole function, which is overwritten each time. To create a new scope (with its own variables), you have to wrap them in their own function. Luckily, jQuery provides an iterating function that you can pass a function to, so that you don't have this issue: $.each. See: http://jsfiddle.net/6rRgr/3/.

$.each(events_fns, function(sel, funcs) {
    $.each(funcs, function(ev, func) {
        $(sel).on(ev,function(){
            console.log(sel+'+'+ev);
            var th = $(this);
            func(th,th.html());
        });
    });
});

Upvotes: 2

Related Questions