Why is blur event not fired in iOS Safari Mobile (iPhone / iPad)?
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.
Related videos on Youtube
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, 2022Comments
-
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 over 11 yearsI 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 about 8 yearsI'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 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 over 3 yearsDon't target every element on the page like this. This spins up a listener for every. Single. Dom. Element. It is horrible for performance.