How to detect iPad Pro as iPad using javascript?
I guess that iPad Pro is upgraded to iPadOS 13 Beta. Since Apple claimed Desktop-Class Browsing with Safari on iPadOS, it seems mobile Safari also mimics macOS behavior and user agent.
So, the short answer is it's not possible.
However you can try workarounds from answers to this question.
PHP mobile detection with new iPadOS/iOS 13
Best I got as a solution was to use javascript:
// iPad check
if( (window.screen.height / window.screen.width == 1024 / 768) ||
(window.screen.height / window.screen.width == 1112 / 834) ||
(window.screen.height / window.screen.width == 1366 / 1024)
) {
// do stuff here
}
Not as perviously intended, but the best solution I have.
How to detect device name in Safari on iOS 13 while it doesn't show the correct user agent?
Indeed, while option change in Settings may be a good solution for the user, as a developer you can't rely on that. It is as weird as to ask the user to not to use dark mode cause your app doesn't support it instead of opt-out of it using plist.
As for me, the most simple way to detect iOS / iPad OS device now:
let isIOS = /iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
The first condition is old-fashioned and works with previous versions,
while the second condition works for iPad OS 13 which now identifies itself as:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)"
which by all platform detectors I know is not detected (for now) neither as mobile nor desktop.
So since iPad OS now calls itself Macintosh, but real macs have no multi-touch support, this solution is ideal to detect iPad OS devices which are the only multi-touch "Macintosh" devices in existence.
P.S.
Also, you may want to augment this checkup for IE exclusion from being detected as an iOS device
let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream
How to detect iOS 13 on JavaScript?
I would like to advice you against detecting operating system or browser from user agent, since they are susceptible to change more than an API for that does, till a reliable stable standard API lands. I have no idea about when this second part will happen.
However, I can suggest to detect feature instead if in this case it is applicable to you.
You can check if the anchor html element
supports download
attribute:
"download" in document.createElement("a") // true in supporting browsers false otherwise
That way you can display
the appropriate html markup depending on the output for each case.
Something like that may help:
function doesAnchorSupportDownload() {
return "download" in document.createElement("a")
}
// or in a more generalized way:
function doesSupport(element, attribute) {
return attribute in document.createElement(element)
}
document.addEventListener("DOMContentLoaded", event => {
if (doesAnchorSupportDownload()) {
anchor.setAttribute("display", "inline"); // your anchor with download element. originally display was none. can also be set to another value other than none.
} else {
image.setAttribute("display", "inline"); // your alone image element. originally display was none. can also be set to another value other than none.
}
});
For example, I use following to detect if I am on an ar quick look supporting browser on iOS:
function doesSupportAnchorRelAR() {
return document.createElement("a").relList.supports("ar");
}
You can also use techniques documented below:
http://diveinto.html5doctor.com/detect.html#techniques
Is there a way to detect if extension is running on iPad vs iPhone
While figuring out macOS vs iOS is fairly simple through using browser.runtime.getPlatformInfo()
, determining iOS vs iPadOS is more difficult.
When the extension popup comes up there are two different behaviors on Safari on iOS. On iPhone it comes up as a full screenwidth menu from the bottom of the screen. On iPad it behaves like Safari on MacOS and the popup comes down from the extension icon in the toolbar and is dynamically sized.
Keep in mind that on iPadOS the popup can also show up as it does on iOS when the browser is in split view. Because of this it's important to track window resize events and to test the popup in and out of split view, across all of the split view sizes.
The only complete solution I've found is using a combination of Swift, Javascript and CSS.
Swift side
In your WebExtension, or wherever you like, you could create a simple function that returns which platform you're on. I use this over browser.runtime.getPlatformInfo()
since the latter can't discern iOS vs iPadOS. Something like:
func getPlatform() -> String {
var platform:String
#if os(iOS)
if UIDevice.current.userInterfaceIdiom == .pad {
platform = "ipados"
}
else {
platform = "ios"
}
#elseif os(macOS)
platform = "macos"
#endif
return platform
}
In order to communicate with the swift side of you application, you'll need to use native messaging from the javascript side - and put the appropriate message handlers on your swift side.
background.js
browser.runtime.sendNativeMessage({name: "getPlatformFromSwiftSide"}, response => {
if (response.platform === "ipados") {
...
} else if (response.platform === "ios") {
...
}
});
SafariWebExtensionHandler.swift
class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
func beginRequest(with context: NSExtensionContext) {
let item = context.inputItems[0] as? NSExtensionItem
let message = item?.userInfo?[SFExtensionMessageKey] as? [String: Any]
guard let name = message?["name"] as? String else {return}
let response = NSExtensionItem()
if name == "getPlatformFromSwiftSide" {
let platform = getPlatform()
response.userInfo = [SFExtensionMessageKey: ["platform": platform]]
}
context.completeRequest(returningItems: [response], completionHandler: nil)
}
}
At this point you can distinguish between iPadOS and iOS. However you still have the issue of whether or not the browser is in split view or not. As mentioned, for certain sizes in split view, the popup on iPadOS is laid out differently and you must account for this.
Currently I am unaware of any methods to easily determine this, outside of CSS media queries or Javascript matchMedia
calls.
Further, calling window
from the popup (or using media queries in the popup context) won't indicate the browser's size, but rather the popups. Since we wan't to know the browser size to determine how to size the popup, the only reliable way I know of accomplishing this is by using browser.tabs.sendMessage
, send a message to the content script requesting the browser window
size.
All of this seems more complicated than it need be, but I know of no other alternatives currently.
Detect if device is iOS
Detecting iOSWith iOS 13 iPad both User agent and platform strings are changed and differentiating between iPad and MacOS seems possible, so all answers below needs to take that into account now.
This might be the shortest alternative that also covers iOS 13:
function iOS() {
return [
'iPad Simulator',
'iPhone Simulator',
'iPod Simulator',
'iPad',
'iPhone',
'iPod'
].includes(navigator.platform)
// iPad on iOS 13 detection
|| (navigator.userAgent.includes("Mac") && "ontouchend" in document)
}
iOS
will be either true
or false
User Agent sniffing is more dangerous and problems appear often.
On iPad iOS 13, the user agent is identical with that of a MacOS 13 computer, but if you ignore iPads this might work still for a while:
var iOS = !window.MSStream && /iPad|iPhone|iPod/.test(navigator.userAgent); // fails on iPad iOS 13
The !window.MSStream
is to not incorrectly detect IE11, see here and here.
Note: Both navigator.userAgent
and navigator.platform
can be faked by the user or a browser extension.
Browser extensions to change userAgent or platform exist because websites use too heavy-handed detection and often disable some features even if the user's browser would otherwise be able to use that feature.
To de-escalate this conflict with users it's recommended to detect specifically for each case the exact features that your website needs. Then when the user gets a browser with the needed feature it will already work without additional code changes.
Detecting iOS versionThe most common way of detecting the iOS version is by parsing it from the User Agent string. But there is also feature detection inference*;
We know for a fact that history API
was introduced in iOS4 - matchMedia API
in iOS5 - webAudio API
in iOS6 - WebSpeech API
in iOS7 and so on.
Note: The following code is not reliable and will break if any of these HTML5 features is deprecated in a newer iOS version. You have been warned!
function iOSversion() {
if (iOS) { // <-- Use the one here above
if (window.indexedDB) { return 'iOS 8 and up'; }
if (window.SpeechSynthesisUtterance) { return 'iOS 7'; }
if (window.webkitAudioContext) { return 'iOS 6'; }
if (window.matchMedia) { return 'iOS 5'; }
if (window.history && 'pushState' in window.history) { return 'iOS 4'; }
return 'iOS 3 or earlier';
}
return 'Not an iOS device';
}
Related Topics
How to Make Autoplay of the Swiper Slider Start Only After the Slider Enters Viewport
How to Write an Onclick Function for a Dynamically Generated Button
How to Mute Video With JavaScript or Jquery
Show Multiple Divs on Button Click
Looping Through a Json Object Containing More Objects and Arrays
How to Wait for Element to Disappear in Cypress
Jquery Click Events Firing Multiple Times
Reactjs: Expected Onclick Listener to Be a Function, Instead Got Type String
How to Count the Entire Number of Rows in a Datatable
Download Image as File in Typescript
How to Unmute Html5 Video With a Muted Prop
How to Trigger a Jquery Function Only Once in One Page, Per Session
In Nest.Js, How to Get a Service Instance Inside a Decorator
Find Duplicate Values in Objects With JavaScript
Alphanumeric, Dash and Underscore But No Spaces Regular Expression Check JavaScript
How to Get the Difference Between Two Arrays of Objects in JavaScript