How to detect browser rendering engine in javascript?
Asked Answered
S

3

9

I read a book calls 'Professional Javascript For Web Developers 2nd edition' and it state that this code can detect browser rendering engine:

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

but it seems like doesn't work, so how this code work to detect browser rendering engine?Thanks

Selfcontained answered 31/5, 2011 at 14:35 Comment(7)
take a good look at navigator object. especially its properties.Hypotaxis
It doesn't work. There is a large chunk of it missing.Amnesia
It's not a good idea to do this. Check out Modernizr for starters. Detecting the browser type accurately is really hard.Vasti
Rendering engine is in window.navigator.userAgent property. You should parse it in order to extract Rendering engine name.Hypotaxis
@Hypotaxis there are a tremendous number of user agent values in the wild. When possible, it's much, much preferable to check for the actual browser features that a page requires.Vasti
Before doing this you probably want to look into Feature Detection over browser detection, its widely regarded as the better way to do things. See for example michaux.ca/articles/…Nephralgia
If I'm not missing anything, a browser is built on top a render engine (gecko, blink, WebKit...). These renderers interpret javascript, so the engine says what you can do with the JS. Looking into docs from mozilla and w3schools, it's possible see some mozilla experimental technology which is not listed in w3. Unfortunately I can't provide an example because I really don't remember any one now, just already occasionally found it.Perverse
P
15

If you read the rest of the chapter and download the source

then you can look at client.js:

It still works in IE10 on win7 and Chrome 67 on Win10

It needs a little change to handle IE11 (Trident/) and Edge(Edge/) - see later

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)

It needs a little change to handle IE11 (Trident/) and 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));
Paramo answered 31/5, 2011 at 14:50 Comment(0)
T
2

The script obviously doesn't work - it just sets a bunch of variables to zero or null and then checks if they're zero or null. My guess would be that this is not the whole script, and that the crucial part is missing.

What one would normally do is read the UserAgent string (I'm too lazy to google how exactly you do that) and throw some regular expressions at it to detect known patterns. This kind of user agent sniffing has a bunch of downsides though:

  1. It's not forward compatible. You don't know which UA strings future browsers are going to use, so most likely, newer browsers will fail your test and receive the most stripped-down version, even though they could easily handle the full-eye-candy-blow-your-mind one.

  2. The UA string isn't reliable. Just because so many websites make the mistake of sniffing, and then not getting updated regularly, users set different UA strings, purposefully reporting a "wrong" render engine. And then they forget to switch it back, causing all sorts of weird behaviour.

  3. Just because someone has a certain render engine doesn't mean you can rely on all features being there. Browsers are highly configurable, and people use all sorts of extensions, blocking things selectively or completely.

Long story short, instead of sniffing the UA string and assuming things are what you think they are, just test features individually and directly.

Treenware answered 31/5, 2011 at 14:48 Comment(3)
But the code by wrox does actually work for IE8, Fx 4, Opera 11 and Mozilla on XPParamo
Quite likely. It works for browsers I can test since 2004. That is 7 years so far. Judging from the code, it will likely continue to work for major browsers and useragents not messing with the main strings. For example works for Fx 5 on Mac tooParamo
@tdammmers - just tested in IE10/Chrome30 on Win 7 - works fineParamo
C
-3

This is just an alternative. If you are really worried about the rendering issue, you can always playground with the screen width, as far as design is concerned.

For Single Page applications, you just need to screen the screen to the correct sizes depending upon the screen width and your requirement... :)

We made use of:

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

For ios, iphone, ipad it's quite easy as you have to play with just fixed sizes or the standard sizes.

For Android, really frustates you, what we found good was to move ahead with the ldpi, mdpi, hdpi, xhdi and max xxhdpi (for tabs) Pixel ranges.

Collete answered 13/1, 2015 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.