cameronstark
7/13/2017 - 12:36 PM

_client.js - Client Side Detection - Width - Browser - Device

_client.js - Client Side Detection - Width - Browser - Device

/* ==========================================================================
   _client.js - Client Side Detection
   
   get width / browser / device
   ========================================================================== */

var _client = {
  browserArray : [],
  deviceArray : [],
  info : {}
};

_client.init = function(){
 var self = this;
 window.onload = function(){
   //Add classes to body
   self.addBodyClasses(); 
   //Set inital load info
   self.info.set();
 };
};

_client.addBodyClasses = function() {
  //Note: classList is not supported fully IE9 Down
  //Adding multiple classes in IE10 not supported
  //https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
  var elm = document.getElementsByTagName("BODY")[0];
  //Get browser and device info
  this.browserArray = this.getBrowserArray(),
  this.deviceArray = this.getDeviceArray();
  //concat and add to body
  browserArray.concat(deviceArray);
  elm.className += ' ' + browserArray.join(' ');
};

//Browser Info - get info object

_client.info.result = {
  width         : 0,
  height        : 0,
  breakpoint    : '',
  browser       : [],
  device        : []
};

_client.info.set = function(windowSize) {
  var _windowSize = windowSize || this.getWindowSize();
  this.result.width = _windowSize.width;
  this.result.height = _windowSize.height;
  this.result.breakpoint = this.getBreakpoint(_windowSize);
  this.result.browser = this.browserArray;
  this.result.device = this.deviceArray;
};

//Browser Widths

_client.widths = {
  // Todo: Would be great to make this into JSON so
  // same across PHP/CSS/JS
  desktop : 1600,
  laptop  : 960,
  tablet  : 768,
  mobile  : 430
};

_client.getWindowSize = function() {
  //Ref : http://stackoverflow.com/questions/3437786/get-the-size-of-the-screen-current-web-page-and-browser-window
  var w = window,
      d = document,
      e = d.documentElement,
      g = d.getElementsByTagName('body')[0],
      x = w.innerWidth || e.clientWidth || g.clientWidth,
      y = w.innerHeight || e.clientHeight || g.clientHeight;
  return { width: x, height: y };
};

_client.getBreakpoint = function(windowSize) {
  var _windowSize = windowSize || this.getWindowSize();
  var w = windowSize.width;
  if( w < this.widths.mobile ) {
    return 'mobile';
  } else if( w < this.widths.tablet && w >= this.widths.mobile ) {
    return 'tablet';
  } else if( w < this.widths.laptop && w >= this.widths.tablet ) {
    return 'laptop';
  } else if( w < this.widths.desktop && w >= this.widths.laptop ) {
    return 'desktop';
  } else if( w >= this.widths.desktop ) {
    return 'large-desktop';
  }
};

//Browser Check
_client.browserCheck = {
  isIE : function(){
    return !!document.documentMode;
  },
  isEdge : function(){
    return !isIE() && !!window.StyleMedia;
  },
  isFF : function(){
    return "undefined" != typeof InstallTrigger;
  },
  isChrome : function(){
    return !!window.chrome && !!window.chrome.webstore;
  },
  isOpera : function(){
    return !!window.opr && !!opr.addons || !!window.opera || navigator.userAgent.indexOf(" OPR/") >= 0;
  },
  isSafari : function(){
    return Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor") > 0;
  }
};

_client.getBrowserArray = function() {
  var browsers = [];
  var addToArray = function(elm){
    this.browsers.push(elm);
  };
  this.browserCheck.isIE()     && addToArray('ie');
  this.browserCheck.isEdge()   && addToArray('edge');
  this.browserCheck.isFF()     && addToArray('ff');
  this.browserCheck.isChrome() && addToArray('chrome');
  this.browserCheck.isOpera()  && addToArray('opera');
  this.browserCheck.isSafari() && addToArray('safari');
  return browsers;
};

//Device Check
_client.deviceCheck = {
  isMacintosh : function(){
    return navigator.platform.indexOf("Mac") > -1;
  },
  isIpad : function(){
    return null !== navigator.userAgent.match(/iPad/i);
  },
  isTouch : function() {
    //Ref : https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
    return ('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch);
  },
  pixelRatio : function() {
    var ratio = window.devicePixelRatio;
    return ratio === 1 ? false : ratio;
  },
  isHtml5 : function() {
    /**
    http://responsivenews.co.uk/post/18948466399/cutting-the-mustard
    ** HTML5 browsers:-
    IE9+
    Firefox 3.5+
    Opera 9+ (and probably further back)
    Safari 4+
    Chrome 1+ (I think)
    iPhone and iPad iOS1+
    Android phone and tablets 2.1+
    Blackberry OS6+
    Windows 7.5+ (new Mango version)
    Mobile Firefox (all the versions we tested)
    Opera Mobile (all the versions we tested)
    ** HTML4 browsers:-
    IE8-
    Blackberry OS5-
    Nokia S60 v6-
    Nokia S40 (all versions)
    All other Symbian variants
    Windows 7 phone (pre-Mango)
    …and many more that are too numerous to mention
    **/
    return 'querySelector' in document && 'addEventListener' in window;
  }
};

_client.getDeviceArray = function() {
  var devices = [];
  var addToArray = function(elm){
    this.devices.push(elm);
  };
  this.deviceCheck.isMacintosh()  && addToArray('mac');
  this.deviceCheck.isIpad()       && addToArray('ipad');
  this.deviceCheck.isTouch()      && addToArray('touch');
  this.deviceCheck.pixelRatio()   && addToArray('ratio-x' + this.deviceCheck.pixelRatio());
  !this.deviceCheck.isHTML5()     && addToArray('html4');
  return devices;
};

//Init
_client.init();