Detect device, browser and version using javascript

The best way to decide which functionality to use is feature detection. If the feature exists then that  functionality is allowed to run. Libraries such as Modernizr give you feature detection out of the box or you can write your own.



However there are still certain instances where you need device, browser and version detection:
- targeting adverts to certain platforms/users
- upgrade your browser messages
- probably more examples but can't think of them right now!

Here is how you can go about browser detection yourself. First we need a list of operating systems and their matching code names within a browser header.

var os = [
    { name: 'Windows Phone', value: 'Windows Phone', version: 'OS' },
    { name: 'Windows', value: 'Win', version: 'NT' },
    { name: 'iPhone', value: 'iPhone', version: 'OS' },
    { name: 'iPad', value: 'iPad', version: 'OS' },
    { name: 'Kindle', value: 'Silk', version: 'Silk' },
    { name: 'Android', value: 'Android', version: 'Android' },
    { name: 'PlayBook', value: 'PlayBook', version: 'OS' },
    { name: 'BlackBerry', value: 'BlackBerry', version: '/' },
    { name: 'Macintosh', value: 'Mac', version: 'OS X' },
    { name: 'Linux', value: 'Linux', version: 'rv' },
    { name: 'Palm', value: 'Palm', version: 'PalmOS' }
]

We also need a list of the browsers we would like to match and their codenames.

var browser = [
    { name: 'Chrome', value: 'Chrome', version: 'Chrome' },
    { name: 'Firefox', value: 'Firefox', version: 'Firefox' },
    { name: 'Safari', value: 'Safari', version: 'Version' },
    { name: 'Internet Explorer', value: 'MSIE', version: 'MSIE' },
    { name: 'Opera', value: 'Opera', version: 'Opera' },
    { name: 'BlackBerry', value: 'CLDC', version: 'CLDC' },
    { name: 'Mozilla', value: 'Mozilla', version: 'Mozilla' }
]

We also need a list of the browser headers we want to check against. These will be joined together as one long string for us to check.

var header = [
    navigator.platform,
    navigator.userAgent,
    navigator.appVersion,
    navigator.vendor,
    window.opera
];

Next is the RegEx helper function which matches a string against the list of items. For our example we will pass in the browser headers as the string, and the os/browsers as the list.

function matchItem(string, data) {
    var i = 0,
        j = 0,
        html = '',
        regex,
        regexv,
        match,
        matches,
        version;
    
    for (i = 0; i < data.length; i += 1) {
        regex = new RegExp(data[i].value, 'i');
        match = regex.test(string);
        if (match) {
            regexv = new RegExp(data[i].version + '[- /:;]([\\d._]+)', 'i');
            matches = string.match(regexv);
            version = '';
            if (matches) { if (matches[1]) { matches = matches[1]; } }
            if (matches) {
                matches = matches.split(/[._]+/);
                for (j = 0; j < matches.length; j += 1) {
                    if (j === 0) {
                        version += matches[j] + '.';
                    } else {
                        version += matches[j];
                    }
                }
            } else {
                version = '0';
            }
            return {
                name: data[i].name,
                version: parseFloat(version)
            };
        }
    }
    return { name: 'unknown', version: 0 };
}

To run the code all we need to do is join the headers into a string. Then use the helper function to match the os list and the browser list against each one.

var agent = header.join(' ');
var os = this.matchItem(agent, os);
var browser = this.matchItem(agent, browser);

After running this output I get the following:


One of the useful things about this version numbering is that it allows you to check the version as a number in javascript. e.g.

if (os.name === 'Windows' && os.version > 6) { } // Windows 8
if (browser.name === 'Chrome' && browser.version < 26) { } // Chrome 0.1 - 25.9

Check out a working jsfiddle here:

http://jsfiddle.net/kmturley/Gd6c8/

No comments:

Post a Comment