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
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.
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.