By utilizing .focus() in iOS8, the virtual keyboard will be displayed and the page will automatically scroll upon touch

In the era before iOS8, when utilizing the Javascript .focus() method on an input element, it seemed as though nothing happened - the virtual keyboard did not make an appearance. However, with the latest iOS 8 update, executing the .focus() method initially seemed ineffective upon page load. Nevertheless, once a user tapped anywhere on the screen, the virtual keyboard would promptly pop up and scroll the page to the focused element. This predicament also occurred when employing the HTML attribute "autofocus."

This alteration has led to complications for iOS8 users visiting my website. When attempting to click a button, the abrupt scrolling and sudden keyboard presence often causes them to accidentally tap a button located further down the screen.

I presume that this is a flaw in iOS8 rather than an intentional feature. Therefore, my query is: what is the most efficient solution to rectify this issue?

Must I consistently check navigator.userAgent to determine if the device is running iOS8 whenever I utilize the .focus() method?

Answer №1

It seems like you've encountered a bug specific to iOS 8. In iOS7, Safari would overlook or leave elements unfocused that were set with focus before the page loaded. This includes both <input autofocus> and input.focus() functions that occur prior to a certain point, possibly during page load (I tested this with an inline script).

In iOS 8, Safari now remembers that the element was focused but doesn't actually focus on it until a touch down event occurs. It then blindly sends a click event to whichever element received the touch up.

Both browsers behave identically for input.focus() executed after page load. They both zoom to the element and bring up the keyboard.

Testing:

The positive news is that you only need to be concerned about new behavior on elements you wish to prefocus. Additionally, while you may need to implement a user-agent workaround, you can use it for all iOS versions since they were already behaving as if autofocusing wasn't enabled:

if (!/iPad|iPhone|iPod/g.test(navigator.userAgent)) {
    element.focus();
}

This seems to be the approach used by http://www.google.com based on some basic user-agent testing:

  • Mac Book Pro: autofocus before page load.
  • iPhone: no autofocus
  • iPad: no autofocus
  • Kit Kat (Android): focus after page load, potentially conducting extra detection for the presence of a software keyboard.

If you haven't already, it's recommended to submit a radar report to Apple at .

Answer №2

For those working on a Cordova project, the solution is as simple as inserting the following line:

<preference name="KeyboardDisplayRequiresUserAction" value="false" />

into your config.xml document. This method has been successfully tested on IOS 8.3 and IOS 8.4.

Answer №3

It appears that there has been an update in iOS 8 which has altered the way the javascript focus() command is handled by default. If you are working on a hybrid app where you have control over Apple's web view facade, the following information is taken directly from Apple's documentation.

A Boolean value that determines if web content can show the keyboard programmatically.

[myWebView setKeyboardDisplayRequiresUserAction:YES];

When this property is set to YES, the user must physically tap the elements in the web view to bring up the keyboard (or any other relevant input view) for that element. When set to NO, a focus event on an element will automatically display the input view associated with it.

The default value of this property is YES.

Based on the last paragraph, it seems like this method call is not just limited to the keyboard. It suggests that it applies to all input views such as drop-down menus and date pickers.

However, I have encountered a bug as this method call does not seem to be functioning correctly for me. The current behavior I am experiencing indicates that it defaults to NO instead.

Answer №4

Here is the answer:

  1. Turn off all input options
  2. Activate the specific input you want to highlight
  3. Direct focus towards that particular input
  4. Switch on the rest of the input choices

Answer №5

If you're tired of adding the userAgent test every time you use jQuery.focus, here's a handy conditional monkeypatch for it.

JavaScript

if (/iPad|iPhone|iPod/g.test(navigator.userAgent)) {
  (function($) {
    return $.fn.focus = function() {
      return arguments[0];
    };
  })(jQuery);
}

CoffeeScript

if /iPad|iPhone|iPod/g.test navigator.userAgent
  (($) ->
    $.fn.focus = ->
      arguments[0]
  )(jQuery)

Keep in mind that I'm using arguments[0] to ensure method chaining like $(el).focus().doSomethingElse() still works smoothly.

Answer №6

After reporting a bug through the Apple Bug Reporter, it was marked as a duplicate by their team. This suggests that they are actively addressing the issue. However, the lack of additional details on the duplicated item or the problem itself is somewhat frustrating. All I am able to observe is that the status of the duplicate item remains 'Open'.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Set the style of the mat-select element

I'm having an issue with my select option in Angular Material. The options look fine, but when I select one, the strong tag disappears. Can anyone help me style only that part? Thank you in advance. <mat-select formControlName="projectId" ...

Transferring Information Among Scenes in SpriteKit

How can I transfer data between different scenes in SpriteKit? I am working on a game with two scenes, the GameScene and the GameOverScene. The score is updated and displayed in the GameScene, but how do I pass this information to the GameOverScene? This ...

Using Multiline Strings for Arguments

Is there a way to successfully pass multi-line strings containing spaces and tabs as a parameter to an express server? Below is the Express.js code snippet which accepts the parameter: app.get('/:prompt', async (req, res) => { ...

Expanding iframe elements

I am having difficulty adjusting the size of the iframe content (within a fixed-sized iframe). Essentially, I would like the content to scale smaller or larger as if the browser's zoom function was being used. Through my CSS experiments, it seems achi ...

Restricting Meteor Publish to specific user (admin) for all collections

Is there a method to exclusively publish all meteor collections to users with the role of {role: "admin"}? The meteor autopublish package grants database access to all clients. Are there any techniques to utilize the autopublish package while implementing ...

An AJAX request will only occur if there is an alert triggered on a particular computer

Here's an interesting issue I encountered with my company's CMS newsletter system. It seems that the AJAX call to send an email works flawlessly in all modern browsers and operating systems, except for one client. This particular client is using ...

Is there a way to swap out multiple characters within a string when using ng-repeat in AngularJS?

How can I replace multiple characters in a string using ng-repeat in AngularJS? I've tried the following code, but it's not working. I need to remove #, _, and . from the strings in my list. How can I achieve this in AngularJS? <body> &l ...

Having trouble binding form data to a React component with the onChange() method?

I've been working on developing an email platform exclusively for myself and encountered a roadblock with this React form not updating state when data is entered. After identifying the issue, it appears that the main problem lies in the React form not ...

Extract image file name and date information (day, month, year) from an HTML form using Angular

The content of the register.component.ts file can be found below: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-register', templateUrl: './register.component.html', styleUrls: [&apo ...

Error: The React styleguidist encountered a ReferenceError due to the absence of the defined

After integrating react styleguidist into my project, I encountered an issue when running npm run styleguidist. The error message states: ReferenceError: process is not defined Here is a snippet from my styleguide.config.js file: module.exports = { ti ...

Exploring the TypeScript compiler API to read and make updates to objects is an interesting

I'm delving into the world of the typescript compiler API and it seems like there's something I am overlooking. I am trying to find a way to update a specific object in a .ts file using the compiler API. Current file - some-constant.ts export co ...

Is there a method in React Native to include the "share" icon in my drawer instead of a button?

How can I add a "share" icon to my drawer? I attempted to insert an icon using <Ionicons name="md-share" size={24} color="black" /> instead of a Button. However, when I do this, the icon is displayed without any title, unlike what I see in the sett ...

The process of eliminating body padding in Nuxt.js

I'm considering building a website using Nuxt.js because I've heard it's both cool and user-friendly. While I do have some knowledge of vue.js, I'm stuck on a particular issue: How can I remove the padding from the body? I understand ...

Having trouble resolving "react-native-screens" from "node_modules eact-navigation-stacklibmoduleviewsStackViewStackViewCard.js"? Here's how to fix it

Here is the command I used for setting up react app routes: npm i react-native-router-flux --save After restarting npm with "npm start," I encountered this error message: Unable to resolve "react-native-screens" from "node_modules\react-navigation- ...

Using placeholder in number and range input in Angular.js to display a placeholder text instead of a value when the input is 0

I am using Angular.js to link a number and range input so they work together with the same value. I have set the default value to 0 when the page loads as $scope.lbs_needed = 0;. My goal is to display a placeholder="0" whenever the user sets the value of e ...

Avoid mutating the prop directly and instead, utilize a data or computed property that is based on the value of the prop. The prop that is being mutated in this case is

Help me understand this issue that Vue is displaying, I am not sure what is going on. This is my progress element: <el-progress :percentage="percentCompleted" v-show="uploadingVideo"></el-progress> data() { return{ percentCompleted: 0 ...

Having trouble transferring files to an unfamiliar directory using Node.js?

const { resolve } = require("path"); const prompt = require('prompt'); const fsPath = require('fs-path'); // Retrieve files from Directory const getFiles = dir => { const stack = [resolve(dir)]; const files = []; whi ...

Ways to display spinner animations during image loading on Next.js?

Currently, I am attempting to implement a spinner display while images are loading on a Next.js website. To achieve this, I am utilizing the NextUI UI library. My website features several cards, and my goal is to showcase a spinner during the image loadin ...

PHP/AJAX user action history manager

Is there a library available that offers undo/redo functionality with a complete history for a web application? One possible solution could be a system using php/javascript/ajax where you can record the opposite action and variable state for each user acti ...

Deleting items from an array in ReactJS

When retrieving a list of users from AWS Cognito, everything works flawlessly. However, the task of iterating over this array and removing users that do not match a specific Client ID is where I'm facing difficulties. What am I doing wrong in this sc ...