Simulating "focus" and "blur" in jQuery .live() method
Asked Answered
I

6

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

Ibbetson answered 29/7, 2009 at 10:33 Comment(1)
$('textarea').bind('focus') works... In your code sample don't you mean "live()"??Modlin
M
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.

Modlin answered 29/7, 2009 at 11:41 Comment(7)
Now go to the jQuery bug tracker and provide the patch. Good job.Hadden
Will die() route to teardown here?Roussillon
Yep, I think so... jQuery takes care of most of it in the background (including the "handling"). Just updated the teardowns so the appropriate events are detached.Modlin
Many Thanks. Solved a problem I was having perfectly.Lezlielg
how do you use this function?Signesignet
NOTE: this is no longer necessary. jQuery 1.4 supports this natively, via the focusin and focusout events.Modlin
Just a suggestion: in the above code sample, +new Date() can be shortened to +new Date. The brackets aren’t required (unless you need to pass arguments, of course).Luciolucita
F
5

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

Fan answered 27/1, 2010 at 4:33 Comment(0)
R
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.

Roussillon answered 29/7, 2009 at 11:39 Comment(1)
Did the port :) (see my answer)Modlin
K
2

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

Koetke answered 3/6, 2010 at 3:39 Comment(0)
E
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);
    }
});
Earthworm answered 31/7, 2012 at 1:25 Comment(0)
I
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.

Interflow answered 16/10, 2009 at 14:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.