使用 jQuery 检测 Safari

Posted

技术标签:

【中文标题】使用 jQuery 检测 Safari【英文标题】:Detect Safari using jQuery 【发布时间】:2011-08-19 11:28:21 【问题描述】:

虽然两者都是基于 Webkit 的浏览器,但 Safari 会在 URL 中对引号进行 urlencode,而 Chrome 则不会。

因此我需要在JS中区分这两者。

jQuery's browser detection docs 将“safari”标记为已弃用。

有没有更好的方法,还是我现在只坚持已弃用的值?

【问题讨论】:

我不知道坚持下去是不是个好主意,虽然我只是浏览了 chrome 上的 $.browser 文档,但它标记为 @987654323 @。 eeek. How to detect Safari, Chrome, IE, Firefox and Opera browser 的可能副本没有用户代理嗅探?. 【参考方案1】:

混合使用feature detectionUseragent 字符串:

    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');

【讨论】:

对于具有副作用的特征检测,48 票对 5 票的比例,显然这是推荐的解决方案。 :) 使其被接受。 作为一个例子来说明这类事情是多么脆弱,这段代码没有检测到 Internet Explorer 11,因为 UA 字符串已更改。见msdn.microsoft.com/en-us/library/ie/hh869301%28v=vs.85%29.aspx Android webview 也会说 Safari,这是不正确的 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) is_explorer = (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) 也支持 IE11 >>> @ 987654322@【参考方案2】:

以下标识 Safari 3.0+ 并将其与 Chrome 区分开来:

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

【讨论】:

就是这样。 TNX!【参考方案3】:

不幸的是,上面的例子也将 android 的默认浏览器检测为 Safari,但事实并非如此。 我用了 navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 && navigator.userAgent.indexOf('Android') == -1

【讨论】:

【参考方案4】:

为了检查 Safari,我使用了这个:

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

它工作正常。

【讨论】:

【参考方案5】:

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

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;

【讨论】:

不错的技巧,但不幸的是它不起作用。由于 location.hash 处理字符串的方式,等式 (location.hash == '#%22blah%22') 将不起作用。 :// 特征检测是可行的方法,但有一种更好的方法,它没有任何副作用。您的 sn-p 可能会干扰其他依赖哈希更改事件的脚本。我已将该问题标记为与this 重复。我已经在 Safari 3.0 - 5.1.3(Mac 和 Windows)中创建并测试了该方法。这是一个单线:)【参考方案6】:

我发现的唯一方法是检查 navigator.userAgent 是否包含 iPhone 或 iPad 字

if (navigator.userAgent.toLowerCase().match(/(ipad|iphone)/)) 
    //is safari

【讨论】:

【参考方案7】:

如果您正在检查浏览器,请使用$.browser。但如果您正在检查功能支持(推荐),请使用$.support

您不应使用 $.browser 来启用/禁用页面上的功能。原因是它不可靠,一般不推荐。

如果您需要功能支持,那么我推荐modernizr。

【讨论】:

教人钓鱼……“有没有更好的方法”——是的,特征检测。 你的意思是location.hash = '"blah"'; if (location.hash == '#%22blah%22') alert('is Safari'); @AndreKR 没错,我会创建一个函数来专门测试您正在检查的功能。 @Greg 你不是在问浏览器.. 你是在测试浏览器。 特征检测很棒,但是当你想要阻止特定浏览器使用 CSS 动画时(例如),因为它有一个错误的实现怎么办?它在技术上支持该功能,但我们想决定为该浏览器禁用它,因为没有这种情况下的体验会更好。【参考方案8】:
//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/

【讨论】:

【参考方案9】:

这将确定浏览器是否为 Safari。

if(navigator.userAgent.indexOf('Safari') !=-1 && navigator.userAgent.indexOf('Chrome') == -1)

    alert(its safari);
else 
    alert('its not safari');

【讨论】:

不幸的是,它不起作用。在 Chrome v66 和 Safari 上测试。【参考方案10】:

我用来检测苹果浏览器引擎,这个简单的javascript条件:

 navigator.vendor.startsWith('Apple')

【讨论】:

这是唯一完美的解决方案:)【参考方案11】:

解决这个问题的一个非常有用的方法是检测浏览器的 webkit 版本并检查它是否至少是我们需要的版本,否则做其他事情。

使用 jQuery 是这样的:

"use strict";

$(document).ready(function() 
    var appVersion                  = navigator.appVersion;
    var webkitVersion_positionStart = appVersion.indexOf("AppleWebKit/") + 12;
    var webkitVersion_positionEnd   = webkitVersion_positionStart + 3;
    var webkitVersion               = appVersion.slice(webkitVersion_positionStart, webkitVersion_positionEnd);
	
    console.log(webkitVersion);

    if (webkitVersion < 537) 
        console.log("webkit outdated.");
     else 
        console.log("webkit ok.");
    ;
);

这为处理浏览器的不同 webkit 实现的问题提供了一个安全且永久的解决方案。

编码愉快!

【讨论】:

【参考方案12】:
    // Safari uses pre-calculated pixels, so use this feature to detect Safari
    var canva = document.createElement('canvas');
    var ctx = canva.getContext("2d");
    var img = ctx.getImageData(0, 0, 1, 1);
    var pix = img.data;     // byte array, rgba
    var isSafari = (pix[3] != 0);   // alpha in Safari is not zero

【讨论】:

【参考方案13】:

通用函数

 var getBrowseActive = function (browserName) 
   return navigator.userAgent.indexOf(browserName) > -1;
 ;

【讨论】:

【参考方案14】:

我的最佳解决方案

function getBrowserInfo() 
  const ua = navigator.userAgent; let tem;
  let M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
  if (/trident/i.test(M[1])) 
    tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
    return  name: 'IE ', version: (tem[1] || '') ;
  
  if (M[1] === 'Chrome') 
    tem = ua.match(/\bOPR\/(\d+)/);
    if (tem != null) 
      return  name: 'Opera', version: tem[1] ;
    
  
  M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
  tem = ua.match(/version\/(\d+)/i);
  if (tem != null) 
    M.splice(1, 1, tem[1]);
  
  return 
    name: M[0],
    version: M[1],
  ;


getBrowserInfo();

【讨论】:

欢迎。感谢您的贡献。由于 SO 上的低质量,不鼓励仅代码响应。请考虑编辑以添加解释如何/为什么这解决了 OP 的问题,甚至是文档的其他支持链接。请注意,随着时间的推移,大多数支持来自高质量的答案,因为各种用户从您的帖子中学到了一些东西以应用于他们自己的编码问题。 SO help center(***.com/help) 中提供了更多信息

以上是关于使用 jQuery 检测 Safari的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 检测表单输入的自动完成

使用jQuery检测元素是不是可见[重复]

如何使用 jquery 检测页面刷新?

使用 jQuery 检测 HTML5 视频播放/暂停状态

使用 jQuery 检测 div 的高度何时发生变化

使用 javascript/jquery 检测 Asp.Net 表单是不是有效