简体   繁体   中英

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

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>

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 .

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.

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
 })

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
})

in the out-most div

<div onclick='click()'>

then in javascript

function click(){}

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 (eg .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.

The simplest solution I've found is to just make document.body "clickable" at page initialization time:

document.body.onclick = function() {};

Then a click anywhere will blur the active element, just like on a desktop browser. Tested on iOS 15.3.1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM