Detecte o Safari usando jQuery

111

Embora ambos sejam navegadores baseados em Webkit, o Safari urlencodifica aspas no URL, enquanto o Chrome não.

Portanto, preciso distinguir entre esses dois em JS.

Os documentos de detecção de navegador da jQuery marcam "safari" como obsoleto.

Existe um método melhor ou apenas continuo com o valor obsoleto por enquanto?

AndreKR
fonte
Eu não sei se ficar com ele é uma boa ideia, eu não verifiquei isso em profundidade, embora eu apenas naveguei até os documentos $ .browser no Chrome e ele sinaliza $.browser.safari === true. eeek.
davin
1
possível duplicata de Como detectar os navegadores Safari, Chrome, IE, Firefox e Opera sem a detecção do agente do usuário ?
Rob W

Respostas:

340

Usando uma mistura de feature detectione Useragentstring:

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

Uso:
if (is_safari) alert('Safari');

Ou apenas para Safari, use isto:

if ( /^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {alert('Its Safari');}
Panos Kal.
fonte
3
Com uma proporção de 48 votos contra 5 votos para uma detecção de recurso com efeitos colaterais, aparentemente esta é a solução recomendada. :) Tornando a resposta aceita.
AndreKR
1
Como um exemplo de quão frágil é esse tipo de coisa, este código não detecta o Internet Explorer 11 porque a string UA foi alterada. Consulte msdn.microsoft.com/en-us/library/ie/hh869301%28v=vs.85%29.aspx
Olly Hodgson
1
O webview do Android também dirá Safari e isso não é correto
Curtis
15
Chrome / Windows relatará como 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
is_explorer = (navigator.userAgent.indexOf ('MSIE')! == -1 || navigator.appVersion.indexOf ('Trident /')> 0) para também oferecer suporte a IE11 >>> stackoverflow.com/a/22242528/2049986
Jacob van Lingen de
74

O seguinte identifica o Safari 3.0+ e o distingue do Chrome:

isSafari = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/)
Brissmyr
fonte
1
Essa é a questão. TNX!
Eugen Sunic
10

infelizmente, os exemplos acima também detectarão o navegador padrão do Android como Safari, o que não é verdade. eu usei navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1 && navigator.userAgent.indexOf('Android') == -1

user3107045
fonte
7

Para verificar o Safari, usei este:

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

Funciona corretamente.

FlamyTwista
fonte
3

Aparentemente, a única solução confiável e aceita seria fazer a detecção de recursos como esta:

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;
AndreKR
fonte
2
Belo truque, mas infelizmente não funciona. A igualdade (location.hash == '#% 22blah% 22') não funcionará devido à forma como location.hash trata a string. : /
Panos Kal.
1
A detecção de recursos é o caminho a percorrer, mas há um método melhor que não tem efeitos colaterais. Seu snippet pode interferir em outros scripts que dependem de eventos de alteração de hash. Eu marquei a pergunta como uma duplicata desta . Criei e testei o método no Safari 3.0 - 5.1.3 (Mac e Windows). É um one-liner :)
Rob W
2

A única maneira que encontrei é verificar se navigator.userAgent contém a palavra do iPhone ou iPad

if (navigator.userAgent.toLowerCase().match(/(ipad|iphone)/)) {
    //is safari
}
Ohrlando
fonte
1

Se você estiver verificando o navegador, use $.browser. Mas se você estiver verificando o suporte a recursos (recomendado), use$.support .

Você NÃO deve usar $ .browser para habilitar / desabilitar recursos na página. O motivo é não confiável e geralmente não recomendado.

Se você precisar de suporte para recursos, recomendo modernizr .

John Strickler
fonte
Ensine um homem a pescar ... "Existe um método melhor" - Sim, detecção de recursos.
John Strickler
Você quer dizer algo como location.hash = '"blah"'; if (location.hash == '#%22blah%22') alert('is Safari');?
AndreKR
@AndreKR Exatamente, eu faria uma função para testar especificamente o recurso que você está procurando.
John Strickler
2
@Greg Você não está perguntando ao navegador .. você está testando o navegador.
John Strickler de
12
A detecção de recursos é ótima, mas e quando você quiser impedir que um determinado navegador use animações CSS (por exemplo), porque tem uma implementação com erros? Ele é tecnicamente compatível com o recurso, mas queremos tomar a decisão de desativá-lo para esse navegador, porque a experiência é melhor sem essa instância.
Phil Ricketts
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/

Code Spy
fonte
0

Uma maneira muito útil de corrigir isso é detectar a versão do webkit do navegador e verificar se é pelo menos o que precisamos; caso contrário, faça outra coisa.

Usando jQuery, funciona assim:

"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.");
    };
});

Isso fornece uma solução segura e permanente para lidar com problemas com diferentes implementações de webkit do navegador.

Boa codificação!

Reicek
fonte
0

Isso determinará se o navegador é Safari ou não.

if(navigator.userAgent.indexOf('Safari') !=-1 && navigator.userAgent.indexOf('Chrome') == -1)
{
    alert(its safari);
}else {
    alert('its not safari');
}
Dushyant Dagar
fonte
Não funciona, infelizmente. Testado no Chrome v66 e Safari.
Jonathan Arbely
0
    // 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
Vitaly
fonte
0

Eu uso para detectar o mecanismo do navegador da Apple, esta simples condição de JavaScript:

 navigator.vendor.startsWith('Apple')
Daniel De León
fonte
0

FUNÇÃO Genérica

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