使用jQuery检测Safari浏览器

124
尽管两者都是基于Webkit的浏览器,但Safari会对URL中的引号进行编码,而Chrome则不会。
因此,我需要在JS中区分这两个浏览器。 jQuery的浏览器检测文档将"safari"标记为已弃用。
是否有更好的方法,还是现在只能坚持使用已弃用的值?

我不确定坚持这个想法是否是一个好主意,因为我还没有深入研究过。不过我只是在 Chrome 上浏览了一下 $ .browser 文档,并且它标记 $.browser.safari === true。哎呀。 - davin
1
是否有可能检测Safari、Chrome、IE、Firefox和Opera浏览器,而不使用用户代理嗅探技术?此问题可能是如何检测Safari、Chrome、IE、Firefox和Opera浏览器的重复。 - Rob W
14个回答

355

使用特性检测Useragent字符串的混合方式:

    var is_opera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
    var is_Edge = navigator.userAgent.indexOf("Edge") > -1;
    var is_chrome = !!window.chrome && !is_opera && !is_Edge;
    var is_explorer= typeof document !== 'undefined' && !!document.documentMode && !is_Edge;
    var is_firefox = typeof window.InstallTrigger !== 'undefined';
    var is_safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

用法:
if (is_safari) alert('Safari');

或者仅对 Safari 使用此代码:

if ( /^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {alert('Its Safari');}

3
由于特征检测带有副作用,48票对5票的比率表明这是推荐的解决方案。 :) 把它设为接受的答案。 - AndreKR
1
作为这种事情有多么脆弱的一个例子,这段代码无法检测到Internet Explorer 11,因为UA字符串已经改变。请参见http://msdn.microsoft.com/en-us/library/ie/hh869301%28v=vs.85%29.aspx。 - Olly Hodgson
1
Android的webview也会显示Safari,这是不正确的。 - Curtis
15
Chrome/Windows会显示为Safari:(Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36) - Blaise
6
为了支持IE11,将is_explorer = (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0)修改为:is_explorer = (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.userAgent.indexOf('Trident/') !== -1)。详情请参阅https://dev59.com/XWEh5IYBdhLWcg3w9nhj#22242528。 - Jacob van Lingen
显示剩余8条评论

79

以下是Safari 3.0+的特点,以及与Chrome的区别:

isSafari = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/)

1
这是一个东西。谢谢! - EugenSunic

10

不幸的是,上述示例也会将 Android 的默认浏览器检测为 Safari,但实际上并不是。我使用了以下代码:navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 && navigator.userAgent.indexOf('Android') == -1


7

我用以下方法来检查Safari:

$.browser.safari = ($.browser.webkit && !(/chrome/.test(navigator.userAgent.toLowerCase())));
if ($.browser.safari) {
    alert('this is safari');
}

它工作得很正确。


3

显然,唯一可靠和被接受的解决方案是像这样进行特性检测:

browser_treats_urls_like_safari_does = false;
var last_location_hash = location.hash;
location.hash = '"blah"';
if (location.hash == '#%22blah%22')
    browser_treats_urls_like_safari_does = true;
location.hash = last_location_hash;

2
不错的技巧,但不幸的是它不起作用。相等性(location.hash == '#%22blah%22')不起作用,因为location.hash处理字符串的方式不同。 :/ - Panos Kalatzantonakis
1
特征检测是正确的方法,但有一种更好的方法没有任何副作用。你的片段可能会干扰依赖哈希更改事件的其他脚本。我已将问题标记为此处的重复。我在Safari 3.0 - 5.1.3(Mac和Windows)中创建并测试了该方法。这是一个一行代码 :) - Rob W

2
我发现的唯一方法是检查navigator.userAgent是否包含iPhone或iPad单词。
if (navigator.userAgent.toLowerCase().match(/(ipad|iphone)/)) {
    //is safari
}

1
如果您正在检查浏览器,请使用$.browser。但是,如果您正在检查功能支持(推荐),请使用$.support
您不应该使用$.browser来启用/禁用页面上的功能。原因是它不可靠,通常也不建议这样做。
如果您需要功能支持,则我建议使用modernizr

@AndreKR 没错,我会编写一个函数专门测试你要检查的功能。 - John Strickler
2
@Greg 你不是在询问浏览器..而是在测试浏览器。 - John Strickler
$.browser已经被弃用,可能很快就会从jQuery核心中移除。请阅读http://api.jquery.com/jQuery.browser/的描述,jQuery团队建议您也使用特性检测。 - John Strickler
@John 是的,你说得对,我想错了,抱歉! - Greg Flynn
12
特征检测很好,但是如果你想阻止特定的浏览器使用CSS动画(例如),因为它有错误的实现呢?虽然该浏览器在技术上支持该特性,但我们希望做出决策,在该实例中禁用它,因为没有它的体验更好。 - Phil Ricketts
显示剩余4条评论

1
这将确定浏览器是否为Safari。
if(navigator.userAgent.indexOf('Safari') !=-1 && navigator.userAgent.indexOf('Chrome') == -1)
{
    alert(its safari);
}else {
    alert('its not safari');
}

很遗憾,不起作用。在Chrome v66和Safari上进行了测试。 - Jonathan Arbely

1
//Check if Safari
  function isSafari() {
      return /^((?!chrome).)*safari/i.test(navigator.userAgent);
  }
//Check if MAC
     if(navigator.userAgent.indexOf('Mac')>1){
        alert(isSafari());
     }

http://jsfiddle.net/s1o943gb/10/


1

我使用以下简单的JavaScript条件来检测苹果浏览器引擎:

 navigator.vendor.startsWith('Apple')

1
这是唯一完美运作的解决方案 :) - Saurabh Chauhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接