diff --git a/backbone.js b/backbone.js index 3a20c864..c6427b69 100644 --- a/backbone.js +++ b/backbone.js @@ -1074,13 +1074,7 @@ var match = key.match(delegateEventSplitter); var eventName = match[1], selector = match[2]; - method = _.bind(method, this); - eventName += '.delegateEvents' + this.cid; - if (selector === '') { - this.$el.on(eventName, method); - } else { - this.$el.on(eventName, selector, method); - } + this.delegate(eventName, selector, method); } return this; }, @@ -1093,6 +1087,21 @@ return this; }, + // Add a single event listener to the element. + delegate: function(eventName, selector, method) { + if (_.isFunction(selector)) { + method = selector; + selector = undefined; + } + eventName += '.delegateEvents' + this.cid; + if (!selector) { + this.$el.on(eventName, _.bind(method, this)); + } else { + this.$el.on(eventName, selector, _.bind(method, this)); + } + return this; + }, + // For hooking into small amounts of DOM Elements, where a full-blown template isn't // needed, use **make** to manufacture elements, one at a time. // diff --git a/test/view.js b/test/view.js index 5635c937..77f531c6 100644 --- a/test/view.js +++ b/test/view.js @@ -76,6 +76,21 @@ equal(counter2, 3); }); + test("delegate", 2, function() { + var counter1 = 0, counter2 = 0; + + var view = new Backbone.View({el: '#testElement'}); + view.increment = function(){ counter1++; }; + view.$el.on('click', function(){ counter2++; }); + + view.delegate('click', 'h1', view.increment); + view.delegate('click', view.increment); + + view.$('h1').trigger('click'); + equal(counter1, 2); + equal(counter2, 1); + }) + test("delegateEvents allows functions for callbacks", 3, function() { var view = new Backbone.View({el: '
'}); view.counter = 0;