18

I want to use navigator.vibrate on my page.

This is my code:

    var canVibrate = "vibrate" in navigator || "mozVibrate" in navigator;
    if (canVibrate && !("vibrate" in navigator))
    {
        navigator.vibrate = navigator.mozVibrate;
    }

    $(document).on('click', '.answer', function (eve) {
        $this = $(this);

        navigator.vibrate(222);

        // some other code ...

This works on Android devices but on iOS (I tested on Firfox, Chrome and Safari on some iOS devices) the code will be broken at this line.

Why is that?

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
Kiyarash
  • 2,437
  • 7
  • 32
  • 61
  • From the developer prospective (trying to build an awesome website), it seems ridiculous that the vibration apis are not exposed for use on iOS; after all, it has been available in other browsers for almost 8 years. But when looked upon from Apple's perspective... think of all the terrible websites that would ruin your browsing experience by spamming vibration. They are smart enough to see that it would turn into another pop-upocalypse. And that is why we can't have nice things. – isaacdre Apr 01 '20 at 01:46
  • 1
    I disagree. The API could require user-interaction to successfully call the function AND there could be user options to control how it works in settings. If the reason Apple hasn't implemented the API in iOS is because it could be abused, then that's literally short-sighted because the API can enable additional haptic feedback for disabled users. A reasonable argument can be made that non-implementation in Safari/Webkit violates the Americans with Disabilities Act (ADA). – CubicleSoft Apr 25 '20 at 15:25
  • I wonder what kind of code would let us use it on Android while letting everything else run on iOS without breaking the execution. Has anyone tested https://github.com/SomaticLabs/haptics.js – HolyResistance Feb 03 '21 at 21:10
  • @isaacdre Then why it didn't break anything for android users? This is one of those flawed logics. If you are so scared about users, then ask them if they want allow vibration for particular site. And if they don't - block it. Simple as that – Andrew Feb 13 '21 at 09:57
  • Interesting point on the ADA CubicleSoft, I wonder if they have reviewed it in that light. @Andrew, I want to clarify, I do not work for/with Apple and I do not have say in what they do. From what I have seen, Apple has a history of tightly controlling access to it's hardware and thus it's brand and I expect this may be a reason behind not enabling haptics for web iOS. Another theory is that Apple doesn't want their phones to vibrate on web because they want to keep the web experience less sophisticated than iOS apps... which obviously means they can control da traffic and $$$ flow. – isaacdre Feb 16 '21 at 22:59

3 Answers3

20

Apple's mobile web browser simply does not have support for it.

Firefox and Chrome for iOS are wrappers around Safari's rendering engine.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    Does this mean that Firefox and Chrome for IOS also do not support navigator.vibrate()? – Barak Binyamin Mar 04 '22 at 05:13
  • @Explorer Yes. Firefox Mobile and Chrome Mobile on iOS aren't the real thing like they are on Android. On iOS, they are _Safari-with-a-Firefox-skin_ and _Safari-with-a-Chrome-skin_. That means: anything iOS Safari Mobile can't do, they can't do either. – Rounin May 01 '22 at 08:41
  • so, there isn't any way to enable that function on iOS devices? not even with an external library? – Joe X Apr 22 '23 at 17:48
13

Quentin is correct that Apple devices do not support the API.

The given code fails to check for vibration support when actually calling the method. To avoid the vibrate function being caught undefined:

const canVibrate = window.navigator.vibrate
if (canVibrate) window.navigator.vibrate(100)
koktavy
  • 350
  • 2
  • 7
  • Nice and simple. This answer is surely better than mine. But I know well that some browsers can actually lie to developers. So we have to double check. If someone tries and verifies this please write here to tell everyone. If it works then this is the ultimate answer. – HolyResistance Jul 31 '21 at 10:19
  • 4
    +1. An alternative is: `const canVibrate = ('vibrate' in navigator);` - but either is as good as the other. – Rounin May 01 '22 at 08:49
  • Conditional (ternary) operator would be even shorter: `window?.navigator?.vibrate?.(100);` – Robin Sep 06 '22 at 12:42
1

We don't want our app to break down and be unusable on iOS devices. But we really want to use navigator.vibrate() on Android or wherever possible. One thing you can do is you can create your own policy over browser policies. Ask "Can we make iOS devices ignore navigator.vibrate()"? The answer is "Well, yes you can do that by using a user agent parser." (Such as Faisal Salman's UAParser to detect if the user's device was an iOS or Mac OS device.) In your code, wrap all the navigator.vibrate() calls inside conditions like,

if(nameOfUsersOS != "iOS" && nameOfUsersOS != "Mac OS") { navigator.vibrate(); }

Note: You must replace nameOfUsersOS with your own variable name.

Note: This is only one possible approach. Policy makers of Apple can and sometimes do change their minds. That means in the future they could allow the good Vibration API just like they allowed the Web Speech API recently. You must use the solution in kotavy's answer unless your policy is like "no vibration for Apple users forever".

HolyResistance
  • 594
  • 1
  • 8
  • 26