43

Suppose I do this:

$(target).blur(function(e){
  //do stuff
});

Is there a way to fetch the object that was clicked on in order to trigger the blur action?

I tried using e.target, but that appears to be returning the object attached to the blur action rather than the clicked object.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
pillarOfLight
  • 8,592
  • 15
  • 60
  • 90
  • 3
    Why is this question marked as a duplicate? I haven't found another question specifically about jQuery's blur event. If it really is a dupe, please link to the duplicate question. – Michael Scheper Apr 01 '15 at 01:14
  • Has anyone found a way to make non-Chromium browsers work in this situation? Tabbing outside of the field cannot be handled in order to get the new focused element, as far as I can tell. `var target = e.toElement || e.relatedTarget;` returns nothing. Crappy specs from crappy spec writers... – user2173353 Nov 23 '15 at 09:22

4 Answers4

49

The trick is to wait an extra tick:

$(el).blur(function (event) {
    // If we just hangout an extra tick, we'll find out which element got focus really
    setTimeout(function(){
       document.activeElement; // This is the element that has focus
    },1);
})
GlabbichRulz
  • 948
  • 9
  • 28
blockhead
  • 9,655
  • 3
  • 43
  • 69
  • 4
    I found that `setTimeout` needed an explicit delay to allow the other `click` event to fire; also for me (jQuery 1.8) `document.activeElement` was `body`, which wasn't very helpful :) – drzaus Mar 10 '13 at 06:16
  • 2
    I should add there might be better ways of doing this, all along the same lines, by using `setImmediate` or `requestAnimationFrame` – blockhead May 15 '14 at 12:10
40

If I understand your question correctly, this should do it:

$(function() {

    var clicky;

    $(document).mousedown(function(e) {
        // The latest element clicked
        clicky = $(e.target);
    });

    // when 'clicky == null' on blur, we know it was not caused by a click
    // but maybe by pressing the tab key
    $(document).mouseup(function(e) {
        clicky = null;
    });

    $(target).blur(function(e) {
        console.log(clicky);
    });​​

});
lex82
  • 11,173
  • 2
  • 44
  • 69
daryl
  • 14,307
  • 21
  • 67
  • 92
7

Inside an event handler, this will be the element the event is bound to, and e.target will be the element that triggered the event (may or not be the same as this).

You are handing a blur event, not a click event. So, inside your event, you will have the element that you blured. If you want the clicked element, you'd need another event to get that.

blur can be triggered by other events, such as focusing something; not just clicking on something. So, there is no way to get the element that "caused the blur".

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • 1
    It's not true that there's no way. Refer to this answer: http://stackoverflow.com/a/11544589/1450294 – Michael Scheper Apr 01 '15 at 02:27
  • 2
    This is easily achievable in Flash/AS3, with the FocusIn and FocusOut events, which include the objects receiving and losing the focus, with simple ability to cancel. Nice to see that in 2018, JavaScript/HTML is now over a decade behind Flash with no easy way to do this. I hate posting comments like this, but the sheer superiority of the AS3 language over JS becomes more and more irritating the longer I watch JS remain terrible and lacking, year after year. – Triynko Mar 13 '18 at 19:05
1

Using this within blur handler function will give you the blurred element.

$(target).blur(function(e){
   var blurredElement = this;  // dom element
   // To make a jQuery object 
   var blurredElement = $(this);
});

Within blur event you can't catch the clicked element. To get the clicked element you need click event. For example:

$(element).click(function() {
  var clickedElement = this;
});

And to get the focused element you can use :focus selector like: $(':focus') will returns you focused element in document.

isherwood
  • 58,414
  • 16
  • 114
  • 157
thecodeparadox
  • 86,271
  • 21
  • 138
  • 164
  • I found that I needed to put `$someElement.is(':focus')` or `$(':focus')` within a `setTimeout` function, triggered by the blur handler, to give some browsers a chance to focus on the next element. – Michael Scheper Apr 01 '15 at 02:25