jQuery's One - Fire once with multiple event types

Instead of using .one, use .on and remove the binding manually with .off.

$('input').on('mouseup keyup', function(e){
    console.log(e.type);
    $(this).off('mouseup keyup');
});

Fiddle: http://jsfiddle.net/23H7J/3/


This can be done a little more elegantly with namespaces:

$('input').on('mouseup.foo keyup.foo', function(e){
    console.log(e.type);
    $(this).off('.foo');
});

This allows us to use a single identifier (foo) to remove any number of bindings, and we won't affect any other mouseup or keyup bindings the element may have.

Fiddle: http://jsfiddle.net/23H7J/41/


Great answers! To wrap them into a function, here's a jQuery extension based off the current answers:

//The handler is executed at most once per element for all event types.
$.fn.once = function (events, callback) {
    return this.each(function () {
        $(this).on(events, myCallback);
        function myCallback(e) {
            $(this).off(events, myCallback);
            callback.call(this, e);
        }
    });
};

Then call like this:

$('input').once('mouseup keyup', function(e){ 
    console.log(e.type);
});

Demo in fiddle

Bonus: This has the added benefit of only detaching the handlers for this specific function by passing in the original handler to the off function. Otherwise, you'll need custom namespaces.

Additionally, if you want a handler to fire only once as soon as any of the elements fire any of the events and then immediately detach itself, then just remove the each from the extension like this:

//The handler is executed at most once for all elements for all event types.
$.fn.only = function (events, callback) {
    var $this = $(this).on(events, myCallback);
    function myCallback(e) {
        $this.off(events, myCallback);
        callback.call(this, e);
    }
    return this
};

To fire once and keep firing, the following snippet may be used:

https://jsfiddle.net/wo0r785t/1/

$.fn.onSingle = function(events, callback){
    if ("function" == typeof(callback)) {
        var t = this;
        var internalCallback = function(event){
            $(t).off(events, internalCallback);
            callback.apply(t, [event]);
            setTimeout(function(){
                $(t).on(events, internalCallback);
            }, 0);
        };
        $(t).on(events, internalCallback);
    }
    return $(this);
};

It works by temporarily disabling the events using the internalCallback function, and asynchronously (setTimeout) enabling it again.

Most other suggestions in this thread disable all future events on the target. However, while OP seems satisfied with previous answers, his question does not mention the permanent disabling of events.