26

Update: As of jQuery 1.4, $.live() now supports focusin and focusout events.


jQuery currently1 doesn't support "blur" or "focus" as arguments for the $.live() method. What type of work-around could I implement to achieve the following:

$("textarea")
  .live("focus", function() { foo = "bar"; })
  .live("blur",  function() { foo = "fizz"; });

1. 07/29/2009, version 1.3.2

Kara
  • 6,115
  • 16
  • 50
  • 57
Sampson
  • 265,109
  • 74
  • 539
  • 565

6 Answers6

31

Working solution:

(function(){

    var special = jQuery.event.special,
        uid1 = 'D' + (+new Date()),
        uid2 = 'D' + (+new Date() + 1);

    jQuery.event.special.focus = {
        setup: function() {
            var _self = this,
                handler = function(e) {
                    e = jQuery.event.fix(e);
                    e.type = 'focus';
                    if (_self === document) {
                        jQuery.event.handle.call(_self, e);
                    }
                };

            jQuery(this).data(uid1, handler);

            if (_self === document) {
                /* Must be live() */
                if (_self.addEventListener) {
                    _self.addEventListener('focus', handler, true);
                } else {
                    _self.attachEvent('onfocusin', handler);
                }
            } else {
                return false;
            }

        },
        teardown: function() {
            var handler = jQuery(this).data(uid1);
            if (this === document) {
                if (this.removeEventListener) {
                    this.removeEventListener('focus', handler, true);
                } else {
                    this.detachEvent('onfocusin', handler);
                }
            }
        }
    };

    jQuery.event.special.blur = {
        setup: function() {
            var _self = this,
                handler = function(e) {
                    e = jQuery.event.fix(e);
                    e.type = 'blur';
                    if (_self === document) {
                        jQuery.event.handle.call(_self, e);
                    }
                };

            jQuery(this).data(uid2, handler);

            if (_self === document) {
                /* Must be live() */
                if (_self.addEventListener) {
                    _self.addEventListener('blur', handler, true);
                } else {
                    _self.attachEvent('onfocusout', handler);
                }
            } else {
                return false;
            }

        },
        teardown: function() {
            var handler = jQuery(this).data(uid2);
            if (this === document) {
                if (this.removeEventListener) {
                    this.removeEventListener('blur', handler, true);
                } else {
                    this.detachEvent('onfocusout', handler);
                }
            }
        }
    };

})();

Tested in IE/FF/Chrome. Should work exactly as you intended.

UPDATE: Teardowns now work.

James
  • 109,676
  • 31
  • 162
  • 175
5

This functionality is now included in jQuery core (as of 1.4.1).

Ville
  • 4,088
  • 2
  • 37
  • 38
2

Looks like the problem is when checking the event.type it returns "focusin" & "focusout"

$('input').live("focus blur", function(event){
    if (event.type == "focusin") {
        console.log(event.type);
    }else{
        console.log(event.type);
    }
});
Alan Mabry
  • 167
  • 1
  • 5
2

live() is jQuery's shortcut to event delegation. To answer your question, see Delegating the focus and blur events.

It's pretty ingenious: for standards compliant browsers he uses event capturing to trap those events. For IE he uses IE's proprietary focusin (for focus) and focusout (for blur) events, which do bubble, allowing traditional event delegation.

I'll leave the porting of it to jQuery as an exercise.

Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
2

they have been added on jquery 1.4.1 ... now .live() function supports fucus and blur events =) Greetings

Matias
  • 21
  • 1
0

one more addition: this solution does not support more than one parameter.

i tried:

$(el).live("focus blur",  function(e) {
  if (e.type == "focus") {

etc.

and it only fired the blur event.

nevertheless this solution has been helpful.

Jason Plank
  • 2,336
  • 5
  • 31
  • 40