Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect Only Mobile Users with "Desktop Mode" Browsers

I know that there are many ways to detect mobiles users (mainly by checking the user agent).

But many mobile browsers have the so called "desktop mode", which provides a bit more functional environment for websites.

Is there a way to provide a specific feature (e.g. a jQuery slider) only to these mobile users, browsing in this mode? The real issue I am having is that, essentially, their user agent is the same in both modes (e.g. "Opera Mini 9.0.1"), so from a webmaster's standpoint - how do I know that they are on a mobile device but are browsing the site in desktop mode?

like image 424
Dzhuneyt Avatar asked Jun 27 '13 13:06

Dzhuneyt


2 Answers

Here's the relevant code for iOS Safari users. Essentially the User Agent loses the reference to iPhone/iPod/iPad in desktop mode, but that info is still present in navigator.platform:

var iOSAgent = window.navigator.userAgent.match(/iPhone|iPod|iPad/);
var iOSPlatform = window.navigator.platform && window.navigator.platform.match(/iPhone|iPod|iPad/);
var iOSRequestDesktop = (!iOSAgent && iOSPlatform);
like image 56
zeroimpl Avatar answered Sep 19 '22 20:09

zeroimpl


On Android Chrome, "Desktop Mode" removes the "Android" string from the user agent. If you can use JavaScript, the following mostly detects Android Chrome Desktop Mode:

var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.appVersion)[1], 10); // also matches AppleWebKit
var isGoogle = webkitVer && navigator.vendor.indexOf('Google') === 0;  // Also true for Opera Mobile and maybe others
var isAndroid = isGoogle && userAgent.indexOf('Android') > 0;  // Careful - Firefox and Windows Mobile also have Android in user agent
var androidDesktopMode = !isAndroid && isGoogle && (navigator.platform.indexOf('Linux a') === 0) && 'ontouchstart' in document.documentElement;

It makes the assumption that Chrome with an ARM processor is Android. The assumption definitely fails for users running Linux on ARM, fails for Android on i686 or MIPS etc (and I haven't been able to test ChromeOS).

For Windows Mobile, you can detect desktop mode by checking for the string "WPDesktop;" in the user agent.

Edit: The code used to use window.chrome and window.chrome.webstore which was a reliable test, but somewhere around Chrome 65 you couldn't use those properties anymore to detect desktop mode. Thanks to @faks for the info.

Edit 2: I now highly recommend against treating "desktop mode" as "mobile mode" but, here are my updated opinions:

  • beware that code detecting desktop mode is really fragile and newer browser versions regularly break sniffing code techniques

  • unless you have a serious bug or critical usability issue, it totally isn't worth sniffing

  • never sniff if you are not actively maintaining the code and testing against beta versions of browsers

  • I use the following for iOS: navigator.vendor.indexOf('Apple') === 0 && 'ontouchstart' in document.body. We need this to set the astonishingly shitty iOS inputMode correctly for iPadOS 13 (old navigator.platform technique now broken in iOS 13 Beta) and avoid other iOS usability bugs with other input types. I think you can check window.screen.width == 768 to sniff iPad (stays same even if orientation change). The sniff will break if Macbook comes out in a touch version.

  • I now use the following for detecting Android desktop mode: 'ontouchstart' in document.body && navigator.platform.indexOf('Linux a') === 0 && (window.chrome || (window.Intl && Intl.v8BreakIterator)). Horrible unreliable sniff, but we really need it because android viewport and pinch zooming (not page zooming) is really broken on Android for our SPA (screen size is not enough as a desktop touch user can use a small window).

like image 40
robocat Avatar answered Sep 22 '22 20:09

robocat