Why is blur event not fired in iOS Safari Mobile (iPhone / iPad)?

42,950

Solution 1

If an anchor has any events attached, the first tap on it in iOS causes the anchor to be put into the hover state, and focused. A tap away removes the hover state, but the link remains focused. This is by design. To properly control an application on iOS, you need to implement touch-based events and react to those instead of desktop ones.

There is a complete guide to using Javascript events in WebKit on iOS.

Solution 2

It's a hack, but you can get .blur to fire by registering a click handler on every DOM element. This removes focus from the previously focused element.

$('*').click();
$('html').css('-webkit-tap-highlight-color', 'rgba(0, 0, 0, 0)');

The second line removes the highlight when elements are clicked.

I know this is sub-optimal, but it may get you going.

Solution 3

If you're working with touch devices you can use the touchleave or touchend event to handle when the user clicks outside the area.

$("a").on('touchleave touchcancel', function () {
      // do something
});

For this to work you need to update your focus function to listen for an on click event as follows

$("a").on("click", function (e) {
      if(e.handled !== true) {
            e.handled = true
      } else {
            return false
      }
      // do something
 })

Solution 4

I have check all the doc in the @NicholasShanks answer, but a little frustrated testing all the events.

Android and iOS:

  • Tested on Android Samsung S9
  • Tested on iOS iPad 5ºgen

Finally i have got a solution: Seems iPad listen to mouseout as blur, and seems android listen perfectly to the blur event, i just add a ternary on this case to attach the right event (previously i have aimed to a mobile or tablet device instead of a computer.

// element >> element you want to trigger
// os >> function that return operative system 'ios' or 'android' in my case

element.addEventListener(os === 'ios' ? 'mouseout' : 'blur', () => {
  // Do something
})

Solution 5

The blur event does not fire because when you click outside the anchor tag on a non-clickable element, iOS ignores the click (and the click event does not fire).

There are a couple of threads regarding this (e.g. .click event not firing in Chrome on iOS). You can fix it by adding cursor: pointer to the <body> or some other element that the click will be performed on.

Share:
42,950

Related videos on Youtube

Mohamed Hussain
Author by

Mohamed Hussain

Senior Front End Developer, creating fast loading high performance RWD Web Pages, Learning and sharing what I learned. Love to avoid costly heavy frameworks and using vanilla JS , HTML, CSS alternatives when possible. Good in vanilla JS, CSS, HTML, PWA Features, jQuery, Angular 1.x , CSS frameworks Foundation, bootstrap.

Updated on March 30, 2022

Comments

  • Mohamed Hussain
    Mohamed Hussain almost 2 years

    I've two event handlers bound to an anchor tag: one for focus and blur.

    The handlers fire on desktop, but in iphone and ipad only focus is fired correctly. Blur is not fired if I click outside the anchor tag (blur fires only when I click some other form elements in the page):

        $("a").focus(function(){
            console.log("focus fired");
        });
    
        $("a").blur(function(){
            console.log("blur fired");
        }); 
    

    HTML:

    <html>
    <form>
        <a href="#">test link</a>
        <div>
        <input type="text" title="" size="38" value="" id="lname1" name="" class="text">
        </div>
        <div style="padding:100px">
            <p>test content</p>
        </div>
    </form>
    </html>
    
  • Mohamed Hussain
    Mohamed Hussain over 11 years
    I Found one more intresting thing in the developer.apple.com/library/safari/#documentation/…, that only when i click the clickable element than only the anchor tag lost focus.
  • ChrisFox
    ChrisFox about 8 years
    I've read the posted guide and still don't see how you detect when an input element has lost focus? Can you please post a code example?
  • Nicholas Shanks
    Nicholas Shanks about 8 years
    @ChrisFox Sorry, I don't have any code examples. You have to tap on another form element to transfer focus (and get a blur event on the previous one).
  • dudewad
    dudewad over 3 years
    Don't target every element on the page like this. This spins up a listener for every. Single. Dom. Element. It is horrible for performance.