4

I was using

var isSafari = /constructor/i.test(window.HTMLElement)

but it's not working for new Safari 10.

Any advice on what to use?

Thanks!

edit: How to detect Safari, Chrome, IE, Firefox and Opera browser? only covers Safari up to version 9

Community
  • 1
  • 1
catico
  • 98
  • 2
  • 9
  • 4
    You shouldn't do browser detection anymore. You should use feature detection. – Liam Aug 24 '16 at 10:30
  • Possible duplicate of [How to detect Safari, Chrome, IE, Firefox and Opera browser?](http://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser) – Liam Aug 24 '16 at 10:30
  • @Liam Unfortunately, in that post the solution was tested in Safari versions between `3.0 - 9.0.3` and not in `10` – David R Aug 24 '16 at 10:37
  • 1
    Which is pretty much why you shouldn't use browser detection. – Liam Aug 24 '16 at 10:38
  • Agree with you on this point, I was just referring to the flagged post. :-) – David R Aug 24 '16 at 10:39
  • @Liam I haven't been able to solve my problem with feature detection, that's why I'm trying to do it with browser detection. – catico Aug 24 '16 at 12:29
  • This does seem like an [XY problem](http://meta.stackexchange.com/a/66378/217110). Maybe better to describe your problem rather than what you think the solution may be? – Liam Aug 24 '16 at 12:31
  • 3
    @Liam Sorry, what I meant to say is that in some cases feature detection is not applicable since the problem is not related to whether some feature is or isn't available. I'm just trying to disable svg filter in Safari where the Gaussian blur is not producing expected result and there doesn't seem to be any other workaround. – catico Aug 24 '16 at 13:21
  • 1
    @Liam right... but how you feature detect Safari's bug with erroneous caching of HTTP range requests? – async5 Nov 04 '16 at 20:48
  • @catico I think you should have a look to Bowser https://github.com/ded/bowser/blob/master/src/bowser.js it detects correctly Safari 10. – Benoit Patra Nov 08 '16 at 18:37

2 Answers2

6

I extended the safari detect line as mentioned in How to detect Safari, Chrome, IE, Firefox and Opera browser? with the following and placed it at the bottom of the list of tests:

isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 || !isChrome && !isOpera && window.webkitAudioContext !== undefined;

It basically checks to see if the web audio API is using the webkit prefix after making sure it is not Chrome or Opera. (older versions of Chrome and Opera also used this prefix)

I went to caniuse.com to see which features are supported in which browsers and tried looking for one that stands out in a way that is specific to Safari.There are possibly other features I could have used. (and there might be better ones).

I know that feature detection is usually the better way except that feature detection doesn't detect if the feature is broken or gives different results depending on the browser.

Community
  • 1
  • 1
  • 1
    This is an incomplete answer. It requires code from the linked question to function correctly. Given that others may edit that answer, it would be better to pull everything needed into this one – Chuck Le Butt Mar 05 '18 at 14:23
6
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari.pushNotification);

Will cover all version of Safari from 3.0 and until 10 (not 11).

It checks for two API diversion prevalent on Safari only. In versions before 9.1.3, the .toString() result of HTMLElement object is [object HTMLElementConstructor] and is unique to Safari. This was fixed in versions after 9.1.3.

For newer versions, check against the [object SafariRemoteNotification] object which is an object type that exists only in modern Safari browsers.

Chuck Le Butt
  • 47,570
  • 62
  • 203
  • 289
pilau
  • 6,635
  • 4
  • 56
  • 69