如何在JavaScript中检测浏览器渲染引擎?

9
我读了一本名为“Web前端开发技术丛书:JavaScript高级程序设计(第2版)”的书,其中提到以下代码可以检测浏览器的渲染引擎:
    <script type="text/javascript">
  var client = function(){
     var engine = {
        ie: 0,
        gecko: 0,
        webkit: 0,
        khtml: 0,
        opera: 0,

        ver: null
     };

     return {
        engine : engine  
     };

  }();

  if(client.engine.ie){
      alert("This is internet explorer");
  }else if(client.engine.gecko > 1.5){
      if(client.engine.ver == "1.8.1"){
          alert("This is gecko rendering browser");
      }
  }else if(client.engine.webkit){
        alert("This is web kit");
  }else if(client.engine.khtml){
       alert("This is khtml");
  }else{
       alert("none of the above");
  }
</script>

但是似乎不起作用,那么这段代码如何检测浏览器渲染引擎呢?谢谢。

1
仔细查看navigator对象,特别是它的属性。 - DrStrangeLove
2
它不起作用。有一大块内容丢失了。 - Quentin
这样做不是一个好主意。首先可以查看Modernizr。准确地检测浏览器类型真的很困难。 - Pointy
1
@DrStrangeLove 在实际应用中,有大量的用户代理值。如果可能的话,最好检查页面所需的实际浏览器功能,这样会更加可靠。 - Pointy
2
在进行此操作之前,您可能希望研究功能检测而非浏览器检测,因为它被广泛认为是更好的方法。例如,请参见http://michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting - Jake
显示剩余2条评论
3个回答

15
如果你阅读完章节下载源代码,那么你可以查看client.js:
它仍然可以在Win7上的IE10和Win10上的Chrome 67中工作。
它需要进行一些小的更改来处理IE11(Trident /)和Edge(Edge /)-稍后再看。

var client = function() {

  //rendering engines
  var engine = {
    ie: 0,
    gecko: 0,
    webkit: 0,
    khtml: 0,
    opera: 0,

    //complete version
    ver: null
  };

  //browsers
  var browser = {

    //browsers
    ie: 0,
    firefox: 0,
    safari: 0,
    konq: 0,
    opera: 0,
    chrome: 0,
    safari: 0,

    //specific version
    ver: null
  };


  //platform/device/OS
  var system = {
    win: false,
    mac: false,
    x11: false,

    //mobile devices
    iphone: false,
    ipod: false,
    nokiaN: false,
    winMobile: false,
    macMobile: false,

    //game systems
    wii: false,
    ps: false
  };

  //detect rendering engines/browsers
  var ua = navigator.userAgent;
  if (window.opera) {
    engine.ver = browser.ver = window.opera.version();
    engine.opera = browser.opera = parseFloat(engine.ver);
  } else if (/AppleWebKit\/(\S+)/.test(ua)) {
    engine.ver = RegExp["$1"];
    engine.webkit = parseFloat(engine.ver);

    //figure out if it's Chrome or Safari
    if (/Chrome\/(\S+)/.test(ua)) {
      browser.ver = RegExp["$1"];
      browser.chrome = parseFloat(browser.ver);
    } else if (/Version\/(\S+)/.test(ua)) {
      browser.ver = RegExp["$1"];
      browser.safari = parseFloat(browser.ver);
    } else {
      //approximate version
      var safariVersion = 1;
      if (engine.webkit < 100) {
        safariVersion = 1;
      } else if (engine.webkit < 312) {
        safariVersion = 1.2;
      } else if (engine.webkit < 412) {
        safariVersion = 1.3;
      } else {
        safariVersion = 2;
      }

      browser.safari = browser.ver = safariVersion;
    }
  } else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)) {
    engine.ver = browser.ver = RegExp["$1"];
    engine.khtml = browser.konq = parseFloat(engine.ver);
  } else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)) {
    engine.ver = RegExp["$1"];
    engine.gecko = parseFloat(engine.ver);

    //determine if it's Firefox
    if (/Firefox\/(\S+)/.test(ua)) {
      browser.ver = RegExp["$1"];
      browser.firefox = parseFloat(browser.ver);
    }
  } else if (/MSIE ([^;]+)/.test(ua)) { // add Trident/ to test IE11, Edge for Edge
    engine.ver = browser.ver = RegExp["$1"];
    engine.ie = browser.ie = parseFloat(engine.ver);
  }

  //detect browsers
  browser.ie = engine.ie;
  browser.opera = engine.opera;


  //detect platform
  var p = navigator.platform;
  system.win = p.indexOf("Win") == 0;
  system.mac = p.indexOf("Mac") == 0;
  system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);

  //detect windows operating systems
  if (system.win) {
    if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)) {
      if (RegExp["$1"] == "NT") {
        switch (RegExp["$2"]) {
          case "5.0":
            system.win = "2000";
            break;
          case "5.1":
            system.win = "XP";
            break;
          case "6.0":
            system.win = "Vista";
            break;
          default:
            system.win = "NT";
            break;
        }
      } else if (RegExp["$1"] == "9x") {
        system.win = "ME";
      } else {
        system.win = RegExp["$1"];
      }
    }
  }

  //mobile devices
  system.iphone = ua.indexOf("iPhone") > -1;
  system.ipod = ua.indexOf("iPod") > -1;
  system.nokiaN = ua.indexOf("NokiaN") > -1;
  system.winMobile = (system.win == "CE");
  system.macMobile = (system.iphone || system.ipod);

  //gaming systems
  system.wii = ua.indexOf("Wii") > -1;
  system.ps = /playstation/i.test(ua);

  //return it
  return {
    engine: engine,
    browser: browser,
    system: system
  };

}();

console.log(client.browser,client.engine,client.system)

需要做一些修改以处理IE11(Trident /)和Edge(Edge /)

var client = function() {

  //rendering engines
  var engine = {
    ie: 0,
    edge: 0,
    gecko: 0,
    webkit: 0,
    khtml: 0,
    opera: 0,

    //complete version
    ver: null
  };

  //browsers
  var browser = {

    //browsers
    ie: 0,
    edge: 0,
    firefox: 0,
    safari: 0,
    konq: 0,
    opera: 0,
    chrome: 0,
    safari: 0,

    //specific version
    ver: null
  };


  //platform/device/OS
  var system = {
    win: false,
    mac: false,
    x11: false,

    //mobile devices
    iphone: false,
    ipod: false,
    nokiaN: false,
    winMobile: false,
    macMobile: false,

    //game systems
    wii: false,
    ps: false
  };

  //detect rendering engines/browsers
  var ua = navigator.userAgent;
  if (window.opera) {
    engine.ver = browser.ver = window.opera.version();
    engine.opera = browser.opera = parseFloat(engine.ver);
  }  
  else if (/Edge\/([^;]+)/.test(ua)) { // IE11
    engine.ver = browser.ver = RegExp["$1"];
    engine.edge = browser.edge = parseFloat(engine.ver);
  } else if (/AppleWebKit\/(\S+)/.test(ua)) {
    engine.ver = RegExp["$1"];
    engine.webkit = parseFloat(engine.ver);

    //figure out if it's Chrome or Safari
    if (/Chrome\/(\S+)/.test(ua)) {
      browser.ver = RegExp["$1"];
      browser.chrome = parseFloat(browser.ver);
    } else if (/Version\/(\S+)/.test(ua)) {
      browser.ver = RegExp["$1"];
      browser.safari = parseFloat(browser.ver);
    } else {
      //approximate version
      var safariVersion = 1;
      if (engine.webkit < 100) {
        safariVersion = 1;
      } else if (engine.webkit < 312) {
        safariVersion = 1.2;
      } else if (engine.webkit < 412) {
        safariVersion = 1.3;
      } else {
        safariVersion = 2;
      }

      browser.safari = browser.ver = safariVersion;
    }
  } else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)) {
    engine.ver = browser.ver = RegExp["$1"];
    engine.khtml = browser.konq = parseFloat(engine.ver);
  } else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)) {
    engine.ver = RegExp["$1"];
    engine.gecko = parseFloat(engine.ver);

    //determine if it's Firefox
    if (/Firefox\/(\S+)/.test(ua)) {
      browser.ver = RegExp["$1"];
      browser.firefox = parseFloat(browser.ver);
    }
  } else if (/MSIE ([^;]+)/.test(ua)) { // IE <= 10
    engine.ver = browser.ver = RegExp["$1"];
    engine.ie = browser.ie = parseFloat(engine.ver);
  } else if (/Trident\/([^;]+)/.test(ua)) { // IE11
    engine.ver = RegExp["$1"];
    browser.ver = parseFloat(ua.split("rv:")[1]);
    engine.ie = parseFloat(browser.ver);
  }

  //detect browsers
  browser.ie = engine.ie;
  browser.opera = engine.opera;


  //detect platform
  var p = navigator.platform;
  system.win = p.indexOf("Win") == 0;
  system.mac = p.indexOf("Mac") == 0;
  system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);

  //detect windows operating systems
  if (system.win) {
    if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)) {
      if (RegExp["$1"] == "NT") {
        switch (RegExp["$2"]) {
          case "5.0":
            system.win = "2000";
            break;
          case "5.1":
            system.win = "XP";
            break;
          case "6.0":
            system.win = "Vista";
            break;
          default:
            system.win = "NT";
            break;
        }
      } else if (RegExp["$1"] == "9x") {
        system.win = "ME";
      } else {
        system.win = RegExp["$1"];
      }
    }
  }

  //mobile devices
  system.iphone = ua.indexOf("iPhone") > -1;
  system.ipod = ua.indexOf("iPod") > -1;
  system.nokiaN = ua.indexOf("NokiaN") > -1;
  system.winMobile = (system.win == "CE");
  system.macMobile = (system.iphone || system.ipod);

  //gaming systems
  system.wii = ua.indexOf("Wii") > -1;
  system.ps = /playstation/i.test(ua);

  //return it
  return {
    engine: engine,
    browser: browser,
    system: system
  };

}();

console.log(JSON.stringify({ browser:client.browser,engine:client.engine,system:client.system},null, 2));


2
这个脚本显然不起作用——它只是把一堆变量设为零或null,然后检查它们是否为零或null。我的猜测是这并不是整个脚本,关键部分可能已经丢失了。
通常做法是读取UserAgent字符串(我太懒了,不想去谷歌如何实现),并对其进行一些正则表达式匹配以检测已知模式。这种用户代理嗅探有许多缺点:
1. 它不具备前向兼容性。你不知道未来的浏览器将使用哪些UA字符串,所以最新的浏览器很可能无法通过测试,只能接收最简化的版本,即使它们可以轻松处理完整的高清图像。
2. UA字符串不可靠。由于很多网站都犯了嗅探的错误,并且没有定期更新,用户设置了不同的UA字符串,故意报告“错误”的渲染引擎。然后他们忘记切换回来,导致各种奇怪的行为。
3. 仅仅因为某个人拥有某个渲染引擎,并不意味着你可以依赖所有功能都在那里。浏览器高度可配置,人们使用各种扩展,选择性或完全阻止某些东西。
简而言之,与其嗅探UA字符串并假设事情就是你认为的那样,不如直接逐个测试功能。

但是Wrox的代码实际上可以在IE8、Fx 4、Opera 11和Mozilla在XP上运行。 - mplungjan
很有可能。自2004年以来,我能测试的浏览器都可以使用。到目前为止已经7年了。从代码来看,它很可能会继续适用于主要浏览器和不会干扰主要字符串的用户代理。例如,在Mac上也可用于Fx 5。 - mplungjan
@tdammmers - 刚在Win 7上的IE10 / Chrome30中进行了测试 - 运行良好。 - mplungjan

-3

这只是另一种选择。如果您真的担心渲染问题,可以根据设计需要随时在屏幕宽度上进行调整。

对于单页应用程序,您只需要根据屏幕宽度和您的需求将屏幕筛选到正确的尺寸即可... :)

我们使用了:

if(screen.width > 360 && screen.width < 720){
    document.write ('<meta name="viewport" content="initial-scale=.25, maximum-scale=.25, user-scalable=no">');
 }

iOS系统下的iPhone和iPad,由于仅涉及固定大小或标准尺寸,开发相对容易。

而Android系统则让人感到非常沮丧,我们发现最好使用ldpi、mdpi、hdpi、xhdi和max xxhdpi(用于平板电脑)像素范围。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接