Chapter 9: Client Detection (Capability Detection, Crazy Detection)

Keywords: IE Attribute

Client Detection

  • Because there are differences among browsers, even cross-platform browsers of the same kind, there are also some differences, which bring difficulties to development. Therefore, client detection is a remedy, which is not necessarily easy to use, try to use a more general method.

Capability testing

  • The purpose of capability testing is not to detect the browser type, but to detect whether the browser has this function. For example, previous versions of IE 5.0 did not support the DOM method of document.getElementById(), but it could be implemented with the document.all attribute:
    function getElement(id) {
        if (document.getElementById) {
            return document.getElementById(id);
        } else if (document.all) {
            return document.all[id];
        } else {
            throw new Error("No way to retrieve element!");
        }
    }
  • There are two points to pay attention to in usability testing: 1. Write a more general and better performance method in front of it. 2. It is necessary to test the features actually used. You can't think of document.all as IE and use the features that IE has.
    function getWindowWidth() {
        if (document.all) { //Suppose IE
            return document.documentElement.clientWidth;//Wrong usage
        } else {
            return window.innerWidth;
        }
    }

More reliable capability testing

  • Direct examples. There's a function like this.
    function isSortable(object) {
        return !!object.sort;//Double exclamation marks are equivalent to Boolean()
    }
  • Can we use this function to detect whether an object supports sorting? The answer is No. When there is a sort attribute in the object, the function also returns true. So we'd better write:
    function isSortable(object) {
        return typeof object.sort == "function";
    }
  • Using the typeof operator does make detection more reliable, but there are exceptions. In IE8 and previous versions, the type of method for DOM objects is object rather than function. This is because DOM objects are host objects, which were implemented by COM rather than JScript in earlier versions of IE. So functions like document.createElement() were indeed a COM object rather than a function in the early days of IE.
    //IE8 and not before
    function hasCreateElement() {
        return typeof document.createElement == "function";
    }
  • In addition, ActiveX objects supported only by IE are quite different from other objects. For example, not applying typeof to detect an attribute can lead to errors:
    var xhr = new ActiveXObject("Microsoft.XMLHttp");
    if (xhr.open) { //The book says there will be errors, but IE9 xhr.open is undefined
        //Perform operations
    }
    function isHostMethod(object, property) {
        var t = typeof object[property];
        return t == "function" || t == "unknown" //IE returns "unknown" to typeof xhr.open
            || !!(t == "object" && object[property]);//COM object and not null
    }
  • Unfortunately, I tested alert (isHost Method (xxxx, open) in IE9; it's still false, and I don't know why.

Capability detection, not browser detection

  • In practical development, capability detection should be used as the basis for determining the next solution, rather than to use it to determine what browser users are using. Here are two typical misuses and two correct uses:
    //Error! Not specific enough. And later Safari implemented the same attributes.
    var isFirefox = !!(navigator.vendor && navigator.vendorSub);
    //Error! The assumption is too much. It is assumed that future versions of IE will implement these two attributes, and other browsers will not.
    var isIE = !!(document.all && document.uniqueID);

    //Verify that the browser supports Netscape style plug-ins
    var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);

    //Determine whether the browser has DOM1 level capabilities
    var hasDOM1 = !!(document.getElementById && document.createElement && 
                   document.getElementsByTagName);

Detection of eccentricity

  • Crazy detection is to find out what's wrong with browsers (that is, bug s). Usually you try to run a piece of code to make sure that a feature doesn't work properly. For example, in IE8 and its earlier versions, if an instance attribute has the same name as an attribute previously marked as non-enumerable, then the attribute will not appear in the for-in loop. There were also previous versions of Safari 3 that enumerated hidden attributes. The following examples can be used to detect eccentricities:
    var hasDontEnumQuirk = function(){
        var o = { toString : function(){} };
        for (var prop in o){
            if (prop == "toString"){
                return false;
            }
        }
        return true;
    }();//Direct execution of anonymous functions
    var hasEnumShadowsQuirk = function(){
        var o = { toString : function(){} };
        var count = 0;
        for (var prop in o){
            if (prop == "toString"){
                count++;
            }
        }
        return (count > 1);
    }();//Direct execution of anonymous functions
    alert(hasDontEnumQuirk);
    alert(hasEnumShadowsQuirk);

Posted by BoltZ on Wed, 10 Jul 2019 18:13:01 -0700