Sto cercando di sintetizzare una classe efficace per il browser Sniffing o browser detect, che dir si voglia.
Voglio analizzare le strategie usate da due script selezionati dalla rete (di cui ahimè non ricordo le fonti).
Os Detecting
L'oggetto navigator ha una proprietà platform
Questa ritorna il sistema operativo del navigator.
Oltre a platform esiste anche un riferimento all'OS usato nella proprietà userAgent.
Quale delle due soluzioni è più performante?
Per quanto sono riuscito a vedere entrambe le proprietà hanno la stessa compatibilità con diversi browser (ho cercato sulla reference di www.w3schools.com/ ).
Esecuzione
Script per conoscere il nome dell'OS
codice:
var p = navigator.platform;
var u = navigator.userAgent;
var tecnicaUsata = u;
//var tecnicaUsata = p;
var OS = searchOS(dataOS, tecnicaUsata) || "OS sconosciuto";
var dataOS =
[
{ subString: "Win", identity: "Windows"},
{ subString: "Mac", identity: "Mac"},
{ subString: "Linux", identity: "Linux"}
];
function searchOS (data, t)
{
for (var i=0; i<data.length; i++)
if (t.indexOf(data[i].subString) != -1)
return data[i].identity;
}
in realtà questa cosa è poco utile (dipende dagli obbiettivi ovviamente).
Più utile è una cosa di questo genere:
codice:
var p = navigator.platform;
var u = navigator.userAgent;
var t = u;
//var t = p;
OSWIN = (t.toLowerCase().indexOf("win") > -1) ? 1 : 0;
OSMAC = (t.toLowerCase().indexOf("mac") > -1) ? 1 : 0;
OSLIN = (t.toLowerCase().indexOf("linux") > -1) ? 1 : 0;
OSOT = (!OSWIN && !OSMAC && !OSLIN) ? 1 : 0;
in questo modo si può usare velocemente una struttura di controllo:
codice:
if (OSWIN) {};
if (OSMAC) {};
[etc...]
Browser Detecting
Qui la situazione si complica a causa della non omogeneità delle intestazioni di userAgent.
Iniziamo con il creare l'array di dati per le tipologie di browser che vogliamo intercettare:
codice:
var dataBrowser =
[
{ string: navigator.userAgent,
subString: "OmniWeb",
versionSearch: "OmniWeb/",
identity: "OmniWeb"
},
{
string: navigator.vendor,
subString: "Apple",
identity: "Safari"
},
{
prop: window.opera,
identity: "Opera"
},
{
string: navigator.vendor,
subString: "iCab",
identity: "iCab"
},
{
string: navigator.vendor,
subString: "KDE",
identity: "Konqueror"
},
{
string: navigator.userAgent,
subString: "Firefox",
identity: "Firefox"
},
{
string: navigator.vendor,
subString: "Camino",
identity: "Camino"
},
{ // for newer Netscapes (6+)
string: navigator.userAgent,
subString: "Netscape",
identity: "Netscape"
},
{
string: navigator.userAgent,
subString: "MSIE",
identity: "Explorer",
versionSearch: "MSIE"
},
{
string: navigator.userAgent,
subString: "Gecko",
identity: "Mozilla",
versionSearch: "rv"
},
{ // for older Netscapes (4-)
string: navigator.userAgent,
subString: "Mozilla",
identity: "Netscape",
versionSearch: "Mozilla"
}
]
la lista è lunga ma credo non sia nemmeno completa.
di seguito la funzione per estrapolare i dati che ci interessano:
codice:
var browser = this.searchString(this.dataBrowser) || "Browser Sconosciuto";
var versionSearchString;
function searchString(dataBrowser)
{
for (var i=0;i<data.length;i++)
{
var dataString = data[i].string;
var dataProp = data[i].prop;
versionSearchString = data[i].versionSearch || data[i].identity;
if (dataString)
{
if (dataString.indexOf(data[i].subString) != -1)
return data[i].identity;
}
else if (dataProp)
return data[i].identity;
}
}
e in fine:
Version Detecting
codice:
var version = searchVersion(navigator.userAgent)
|| searchVersion(navigator.appVersion)
|| "versione sconosciuta";
function searchVersion(dataString)
{
var index = dataString.indexOf(versionSearchString);
if (index == -1) return;
return parseFloat(dataString.substring(index+versionSearchString.length+1));
}
Metodo alternativo
codice:
OP = ((ind1 = navigator.userAgent.indexOf("Opera")) > -1) ? 1 : 0;
punto = (OP) ? navigator.userAgent.indexOf(".",ind1):0;
OP5 = (OP && parseInt(navigator.userAgent.substr(punto-1)) == 5) ? 1 : 0;
OP6 = (OP && parseInt(navigator.userAgent.substr(punto-1)) == 6) ? 1 : 0;
IE = ((ind2 = navigator.appVersion.indexOf("MSIE")) > -1 && !OP) ? 1 : 0;
IE4 = (IE && parseInt(navigator.appVersion.substr(ind2+5)) == 4) ? 1 : 0;
IE5 = (IE && parseInt(navigator.appVersion.substr(ind2+5)) == 5) ? 1 : 0;
IE6 = (IE && parseInt(navigator.appVersion.substr(ind2+5)) == 6) ? 1 : 0;
NN = (navigator.appName.indexOf("Netscape")>-1) ? 1 : 0;
NN4 = (NN && parseInt(navigator.appVersion)==4) ? 1 : 0;
NN6 = (NN && parseInt(navigator.appVersion)>4) ? 1 : 0;
OT = (!IE && !NN && !OP) ? 1 : 0;
Questo metodo è più sintetico e si rivolge solo a determinati browser (che per finalità di gestione dei comportamenti DOM credo siapiù che sufficiente.
Conclusioni
Queste sono le tecniche migliori che sono riuscito a trovare in rete.
Voi quali usate?
Come costruireste voi una classe per gestire il browser sniffing?