diff --git a/src/jqLite.js b/src/jqLite.js index c1b5b36ec444..e59805147886 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -54,6 +54,7 @@ * - [`next()`](http://api.jquery.com/next/) - Does not support selectors * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors + * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors * - [`prepend()`](http://api.jquery.com/prepend/) * - [`prop()`](http://api.jquery.com/prop/) @@ -744,6 +745,19 @@ forEach({ off: jqLiteOff, + one: function(element, type, fn) { + element = jqLite(element); + + //add the listener twice so that when it is called + //you can remove the original function and still be + //able to call element.off(ev, fn) normally + element.on(type, function onFn() { + element.off(type, fn); + element.off(type, onFn); + }); + element.on(type, fn); + }, + replaceWith: function(element, replaceNode) { var index, parent = element.parentNode; jqLiteDealoc(element); diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js index 3a8fd4045c5b..931f9b2e5cb3 100644 --- a/test/jqLiteSpec.js +++ b/test/jqLiteSpec.js @@ -1177,6 +1177,63 @@ describe('jqLite', function() { } }); + describe('one', function() { + + it('should only fire the callback once', function() { + var element = jqLite(a); + var spy = jasmine.createSpy('click'); + + element.one('click', spy); + + browserTrigger(element, 'click'); + expect(spy).toHaveBeenCalledOnce(); + + browserTrigger(element, 'click'); + expect(spy).toHaveBeenCalledOnce(); + }); + + it('should deregister when off is called', function() { + var element = jqLite(a); + var spy = jasmine.createSpy('click'); + + element.one('click', spy); + element.off('click', spy); + + browserTrigger(element, 'click'); + expect(spy).not.toHaveBeenCalled(); + }); + + it('should return the same event object just as on() does', function() { + var element = jqLite(a); + var eventA, eventB; + element.on('click', function(event) { + eventA = event; + }); + element.one('click', function(event) { + eventB = event; + }); + + browserTrigger(element, 'click'); + expect(eventA).toEqual(eventB); + }); + + it('should not remove other event handlers of the same type after execution', function() { + var element = jqLite(a); + var calls = []; + element.one('click', function(event) { + calls.push('one'); + }); + element.on('click', function(event) { + calls.push('on'); + }); + + browserTrigger(element, 'click'); + browserTrigger(element, 'click'); + + expect(calls).toEqual(['one','on','on']); + }); + }); + describe('replaceWith', function() { it('should replaceWith', function() {