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?


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

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

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

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


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.


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;

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
}

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 .


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


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!


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

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

0

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

 navigator.vendor.startsWith('Apple')

0

FUNÇÃO Genérica

 var getBrowseActive = function (browserName) {
   return navigator.userAgent.indexOf(browserName) > -1;
 };
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.