Contenido

¿Como detectan el navegador los diferentes frameworks Javascript?

1 dic

+ 2

Detectar el navegador no siempre es la mejor solución para condicionar nuestros scripts, siempre que podamos deberíamos detectar si las funcionalidades que vamos a ejecutar están disponibles y en caso de no estarlo ofrecer una alternativa, sin importar el navegador. Pero, como bien sabemos, no siempre podemos hacer lo correcto.

En estos casos, saber como lo hacen los frameworks Javascript más usados nos permitirá hacernos una idea de como actuar frente a este problema.

jQuery

Aunque desde la versión 1.3 el atributo browser está desaprovado, aún está disponible en el código para que se vayan migrando los scripts. Supongo que en breve dejará de estar, dejando paso a la detección de funcionalidades.

var userAgent = navigator.userAgent.toLowerCase();
// Figure out what browser is being used
jQuery.browser = {
	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
	safari: /webkit/.test( userAgent ),
	opera: /opera/.test( userAgent ),
	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};

En este caso, hace uso del userAgent para comprobar mediante expresiones regulares el navegador del usuario. Se trata de una comprobación muy genérica y que no nos permite detectar móviles.

MooTools

Por otro lado, MooTools, nos ofrece un objeto (Browser) que nos permite detectar el motor de renderizado sin importar el navegador.

var Browser = $merge({
  Engine: {name: 'unknown', version: 0},
  Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
  Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)},
  Plugins: {},
  Engines: {
    presto: function(){
      return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925));
    },
    trident: function(){
      return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4);
    },
    webkit: function(){
      return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);
    },
    gecko: function(){
      return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18);
    }
  }
}, Browser || {});

Como podemos ver, se encarga de realizar una serie de comprobaciones de funcionalidades para determinar el motor de renderizado que está usando el visitante.

Prototype

Prototype, al igual que MooTools nos ofrece un objeto (Browser) que nos ofrece la versión del navegador.

Browser: (function(){
   var ua = navigator.userAgent;
   // Opera (at least) 8.x+ has "Opera" as a [[Class]] of `window.opera`
   // This is a safer inference than plain boolean type conversion of `window.opera`
   var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
   return {
     IE: !!window.attachEvent && !isOpera,
     Opera: isOpera,
     WebKit: ua.indexOf('AppleWebKit/') > -1,
     Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
     MobileSafari: /Apple.*Mobile.*Safari/.test(ua)
   }
 })(),

Al igual que jQuery comprueba el navegador mediante expresiones regulares simples que no nos permite detectar versiones móviles.

YUI

YUI nos ofrece un atributo que nos indicará el navegador que está usando el usuario.

ua = nav && nav.userAgent,
if (ua) {

  if ((/windows|win32/i).test(ua)) {
    o.os = 'windows';
  } else if ((/macintosh/i).test(ua)) {
    o.os = 'macintosh';
  }

  // Modern KHTML browsers should qualify as Safari X-Grade
  if ((/KHTML/).test(ua)) {
    o.webkit=1;
  }
  // Modern WebKit browsers are at least X-Grade
  m=ua.match(/AppleWebKit\/([^\s]*)/);
  if (m&&m[1]) {
    o.webkit=numberfy(m[1]);

    // Mobile browser check
    if (/ Mobile\//.test(ua)) {
      o.mobile = "Apple"; // iPhone or iPod Touch
    } else {
      m=ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/);
      if (m) {
        o.mobile = m[0]; // Nokia N-series, Android, webOS, ex: NokiaN95
      }
    }

    m=ua.match(/AdobeAIR\/([^\s]*)/);
    if (m) {
      o.air = m[0]; // Adobe AIR 1.0 or better
    }

  }

  if (!o.webkit) { // not webkit
    // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
    m=ua.match(/Opera[\s\/]([^\s]*)/);
    if (m&&m[1]) {
      o.opera=numberfy(m[1]);
      m=ua.match(/Opera Mini[^;]*/);
      if (m) {
        o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
      }
    } else { // not opera or webkit
      m=ua.match(/MSIE\s([^;]*)/);
      if (m&&m[1]) {
        o.ie=numberfy(m[1]);
      } else { // not opera, webkit, or IE
        m=ua.match(/Gecko\/([^\s]*)/);
        if (m) {
          o.gecko=1; // Gecko detected, look for revision
          m=ua.match(/rv:([^\s\)]*)/);
          if (m&&m[1]) {
            o.gecko=numberfy(m[1]);
          }
        }
      }
    }
  }
}

Al igual que jQuery y Prototype, recurre a las expresiones regulares para detectar el navegador, con la diferencia de que esta implementación nos permite detectar alguna versión más de las disponibles.

  • Yo suelo detectar si estoy trabajando con Explorer sobre todo para efectos de CSS.
    Cuando haces un fade con una capa con background en png en IE la parte semitransparente se ve como una mancha negra horrible.

    Por eso diferencio (cuando merece la pena, claro)

    if ('\v'=='v') $('#div').hide(); //IE 
    else $('#div').fadeOut(); //No IE

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.