Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome (maybe Safari?) fires "blur" twice on input fields when browser loses focus

Tags:

Here is an interesting jsfiddle.

In Firefox:

  1. Run the fiddle
  2. Click in text input
  3. Click somewhere else. Should say "1 blurs".
  4. Click in the text input again.
  5. ALT-TAB to another window. Fiddle should now say "2 blurs".

In Chrome, at step 5, it says "3 blurs". Two separate "blur" events are fired when the whole browser loses focus. This is of interest because it means that it's not safe to assume, in a "blur" handler, that the element actually had focus just before the event was dispatched; that is, that the loss of focus — the transition from "being in focus" to "not being in focus" — is the reason for the event. When two "blur" events are generated, that condition is not satisfied during the handling of the second event, as the element is already not in focus.

So is this just a bug? Is there a way to tell that a "blur" event is bogus?

like image 282
Pointy Avatar asked Mar 10 '12 20:03

Pointy


People also ask

What triggers Onblur?

The onblur event occurs when an object loses focus. The onblur event is most often used with form validation code (e.g. when the user leaves a form field). Tip: The onblur event is the opposite of the onfocus event. Tip: The onblur event is similar to the onfocusout event.

How do you stop blur on input?

If you want to prevent the blur event from being fired, you have to do so when you are inside the mousedown event, you can do so by invoking the method preventDefault() on the event. Click the checkbox, focus input & then click the button, the textfield never loses focus now.

What is input blur event?

The blur event fires when an element has lost focus. The main difference between this event and focusout is that focusout bubbles while blur does not. The opposite of blur is focus . This event is not cancelable and does not bubble.

Is blur an event handler?

blur( [eventData ], handler ) An object containing data that will be passed to the event handler. A function to execute each time the event is triggered.


2 Answers

The reason it is firing twice is because of window.onblur. The window blurring triggers a blur event on all elements in that window as part of the way javascript's capturing/bubbling process. All you need to do is test the event target for being the window.

var blurCount = 0; var isTargetWindow = false; $(window).blur(function(e){     console.log(e.target);     isTargetWindow = true; }); $(window).focus(function(){     isTargetWindow = false; }); $('input').blur(function(e) {     if(!isTargetWindow){                 $('div').text(++blurCount + ' blurs');     }     console.log(e.target); }); 

​ http://jsfiddle.net/pDYsM/4/

like image 74
Fresheyeball Avatar answered Sep 20 '22 16:09

Fresheyeball


This is confirmed Chrome bug. See the Chromium Issue Tracker

The workaround is in the accepted answer.

like image 40
Chad Killingsworth Avatar answered Sep 18 '22 16:09

Chad Killingsworth