Mobile Safari: javascript focus () method on input field only works with click?

I can not find a solution to this problem.

I have a simple input field like this.

<div class="search"> <input type="text" value="yu no work"/> </div>​ 

And I'm trying to focus() inside a function. So inside a random function (no matter what function it is) I have this line ...

 $('.search').find('input').focus(); 

This works great on any desktop.

However, it does not work on my iPhone. The field does not focus and the keyboard does not appear on my iPhone.

For testing purposes and to show you guys, I made a quick example:

 $('#some-test-element').click(function() { $('.search').find('input').focus(); // works well on my iPhone - Keyboard slides in }); setTimeout(function() { //alert('test'); //works $('.search').find('input').focus(); // doesn't work on my iPhone - works on Desktop }, 5000);​ 

Any idea why focus() won't work with the timeout function on my iPhone.

To see a live example, check this script on your iPhone. http://jsfiddle.net/Hc4sT/

Update:

I created the same case as in my current project.

I have a select-box that should - when "change" - set focus to the input field and insert kexboard on iphone or other mobile devices. I found out that focus () is set correctly, but the keyboard is not displayed. I need a keyboard to display.

I downloaded the test files right here http://cl.ly/1d210x1W3Y3W ... If you check this on the iphone, you will see that the keyboard is not slide-in.

+55
javascript jquery input iphone focus
Aug 30 '12 at 20:00
source share
8 answers

Actually guys, there is a way. I struggled to figure this out for http://forstartersapp.com (try it on an iPhone or iPad).

Basically, Safari on touchscreen devices is sparingly when it comes to focus() text fields. Even some desktop browsers are better if you do click().focus() . But Safari developers on touch-screen devices realized that it annoyed users as the keyboard continued to rise, so they only focused on the following conditions:

1) The user clicked somewhere and focus() was called during the execution of the click event. If you are making an AJAX call, you must do this synchronously, for example, with the deprecated (but still available) option $.ajax({async:false}) in jQuery.

2) Besides - and it made me take some time - focus() still does not work if some other text field is concentrated at that time. I had a Go button that had AJAX in it, so I tried to blur the text box in the Go button's touchstart event, but it just made the keyboard disappear and moved the viewport before I had the opportunity to finish clicking on the Go button. Finally, I tried to blur the text box in the touchend event of the touchend button, and it worked like a charm!

When you put # 1 and # 2 together, you get a magical result that will set your login forms separately from all the damaged login forms, placing focus in your password fields and making them feel more familiar. Enjoy! :)

+68
May 17 '13 at 4:14
source share

I recently ran into the same issue. I found a solution that apparently works for all devices. You cannot perform asynchronous focusing programmatically, but you can switch the focus to the target input when some other input is already focused. Therefore, you need to create, hide, add to the DOM and focus the false input on the trigger event, and when the asynchronous action completes, just call focus on the target input again. Here is an example of a snippet - run it on your mobile phone.

edit:

Here is the fiddle with the same code . Obviously, you cannot run attached snippets on mobile phones (or I'm doing something wrong).

 var $triggerCheckbox = $("#trigger-checkbox"); var $targetInput = $("#target-input"); // Create fake & invisible input var $fakeInput = $("<input type='text' />") .css({ position: "absolute", width: $targetInput.outerWidth(), // zoom properly (iOS) height: 0, // hide cursor (font-size: 0 will zoom to quarks level) (iOS) opacity: 0, // make input transparent :] }); var delay = 2000; // That crazy long, but good as an example $triggerCheckbox.on("change", function(event) { // Disable input when unchecking trigger checkbox (presentational purpose) if (!event.target.checked) { return $targetInput .attr("disabled", true) .attr("placeholder", "I'm disabled"); } // Prepend to target input container and focus fake input $fakeInput.prependTo("#container").focus(); // Update placeholder (presentational purpose) $targetInput.attr("placeholder", "Wait for it..."); // setTimeout, fetch or any async action will work setTimeout(function() { // Shift focus to target input $targetInput .attr("disabled", false) .attr("placeholder", "I'm alive!") .focus(); // Remove fake input - no need to keep it in DOM $fakeInput.remove(); }, delay); }); 
 label { display: block; margin-top: 20px; } input { box-sizing: border-box; font-size: inherit; } #container { position: relative; } #target-input { width: 250px; padding: 10px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div id="container"> <input type="text" id="target-input" placeholder="I'm disabled" /> <label> <input type="checkbox" id="trigger-checkbox" /> focus with setTimetout </label> </div> 
+5
Aug 15 '17 at 23:34 on
source share

I managed to get it to work with the following code:

 event.preventDefault(); timeout(function () { $inputToFocus.focus(); }, 500); 

I use AngularJS, so I created a directive that solved my problem:

Directive

 angular.module('directivesModule').directive('focusOnClear', [ '$timeout', function (timeout) { return { restrict: 'A', link: function (scope, element, attrs) { var id = attrs.focusOnClear; var $inputSearchElement = $(element).parent().find('#' + id); element.on('click', function (event) { event.preventDefault(); timeout(function () { $inputSearchElement.focus(); }, 500); }); } }; } ]); 

How to use the directive:

 <div> <input type="search" id="search"> <i class="icon-clear" ng-click="clearSearchTerm()" focus-on-clear="search"></i> </div> 

It sounds like you're using jQuery, so I don't know if the directive is any help.

+2
Apr 15 '14 at 11:12
source share

I have a search form with an icon that clears the text when clicked. However, the problem (on mobile devices and tablets) was that the keyboard crashed / hid because the remote click event removed by focus was removed from input .

text search input with close icon

Purpose : cleaning the search form (tapping / tapping the x icon) to keep the keyboard visible !

To accomplish this, apply stopPropagation() to the event like this:

 function clear ($event) { $event.preventDefault(); $event.stopPropagation(); self.query = ''; $timeout(function () { document.getElementById('sidebar-search').focus(); }, 1); } 

And the HTML form:

 <form ng-controller="SearchController as search" ng-submit="search.submit($event)"> <input type="search" id="sidebar-search" ng-model="search.query"> <span class="glyphicon glyphicon-remove-circle" ng-click="search.clear($event)"> </span> </form> 
+2
Nov 25 '15 at 17:57
source share

UPDATE

I also tried this, but to no avail:

 $(document).ready(function() { $('body :not(.wr-dropdown)').bind("click", function(e) { $('.test').focus(); }) $('.wr-dropdown').on('change', function(e) { if ($(".wr-dropdow option[value='/search']")) { setTimeout(function(e) { $('body :not(.wr-dropdown)').trigger("click"); },3000) } }); 

});

I am confused why you say this does not work, because your JSFiddle is working fine, but here is my suggestion anyway ...

Try this line of code in your SetTimeOut function in the click event:

 document.myInput.focus(); 

myInput correlates with the input tag name attribute.

 <input name="myInput"> 

And use this code to blur the field:

 document.activeElement.blur(); 
+1
Aug 30 2018-12-12T00:
source share

This solution works well, I tested on my phone:

 document.body.ontouchend = function() { document.querySelector('[name="name"]').focus(); }; 

to use

+1
Feb 12 '16 at 17:32
source share

WunderBart implementation for native JavaScript implementation.

Disable auto-zoom using font size .

 function onClick() { // create invisible dummy input to receive the focus first const fakeInput = document.createElement('input') fakeInput.setAttribute('type', 'text') fakeInput.style.position = 'absolute' fakeInput.style.opacity = 0 fakeInput.style.height = 0 fakeInput.style.fontSize = '16px' // disable auto zoom // you may need to append to another element depending on the browser auto // zoom/scroll behavior document.body.prepend(fakeInput) // focus so that subsequent async focus will work fakeInput.focus() setTimeout(() => { // now we can focus on the target input targetInput.focus() // cleanup fakeInput.remove() }, 1000) } 
0
Apr 12 '19 at 13:16
source share

Please try using on-tap instead of the ng-click event. I had this problem. I solved this by setting the explicit search button in the search form box and replacing the ng-click of the clear button with the click of a button. Now it works great.

-3
May 2 '16 at 7:17
source share



All Articles