I have roughly translated some Article , Which may be incorrect. please correct me. It is worth noting that the comments are also worth reading.
Feature Detection
At first, front-end engineers opposed browser detection. They thought the User-Agent sniffing method was very bad because it was not a future-oriented method.Code, Cannot adapt to the new version of the browser. A better way is to use feature detection, like this:Copy codeThe Code is as follows: if (navigator. useragent. indexof ("MSIE 7")>-1 ){
// Do something
}
The better practice is as follows:Copy codeThe Code is as follows: if (document. All ){
// Do something
}
These two methods are different. The former is the special name and version of the browser, while the latter is the characteristic of the browser. UA sniffing can accurately obtain the browser type and version (at least the browser type can be known), while feature detection determines whether the browser has an object or supports a method. Note that the two are completely different.
Because Feature Detection depends on the browser support, it requires tedious validation when a new version of the browser appears. For example, when the DOM standard emerged, not all browsers support the getelementbyid () method, so the initial code may be as follows:Copy codeThe Code is as follows: if (document. getelementbyid) {// dom
Element = Document. getelementbyid (ID );
} Else if (document. All) {// IE
Element = Document. All [ID];
} Else if (document. layers) {// Netscape <6
Element = Document. Layers [ID];
}
This is a good example of feature detection. The highlight is that you do not have to modify the code when other browsers start to support the getelementbyid () method.
Hybrid mode
Later, the front-end engineers considered the Improved Writing method, and the code changed to this:Copy codeThe Code is as follows: // avoid !!!
If (document. All) {// IE
Id = Document. uniqueid;
} Else {
Id = math. Random ();
}
The problem with this code is to check whether the document. All attribute is IE. After IE is determined, it is assumed that the private document. uniqueid attribute is secure. However, the current task is to determine whether document. All is supported, not to identify whether the browser is IE. Only document. All is supported, which does not mean document. uniqueid is available.
Later, people started writing like this and replaced the above with the following line:
VaR isie = navigator. useragent. indexof ("MSIE")>-1;
// The following line replaces the above line
VaR isie = !! Document. All; these changes indicate that there is a misunderstanding about "do not use UA sniffing". Instead, we will not detect the details of the browser. Instead, we will infer the changes through feature support. This method based on browser features is very poor.
Later, the front-end found that document. All was not reliable, and the better ie detection was changed:
VaR isie = !! Document. All & document. uniqueid; this implementation method goes astray. It is not only time-consuming to identify the added feature support of the browser, but also cannot be determined that other browsers start to support the same feature.
If you think this code is not widely used, let's look at the original version of mootools code snippet: Copy code The Code is as follows: // from mootools 1.1.2
If (window. activexobject) window. Ie = Window [window. XMLHttpRequest? 'Ie7': 'ie6'] = true;
Else if (document. childnodes &&! Document. All &&! Navigator. taintenabled) window. WebKit = Window [window. XPath? 'Webkit420': 'webkit419'] = true;
Else if (document. getboxobjectfor! = NULL | window. Window innerscreenx! = NULL) window. Gecko = true;
Note how it uses feature detection. I can point out a series of problems. For example, if we detect window. ie, We will mistake IE8 as IE7.
Yubo
With the rapid development of browsers, it is increasingly difficult and unreliable to use feature detection. However, mootools 1.2.4 still uses this method, for example, getboxobjectfor (). Copy code The Code is as follows: // from mootools 1.2.4
VaR browser = $ Merge ({
Engine: {Name: 'unknown ', version: 0 },
Platform: {name: (window. Orientation! = Undefined )? 'Ipod ': (navigator. Platform. Match (/MAC | win | Linux/I) | ['other']) [0]. tolowercase ()},
Features: {XPath :!! (Document. Evaluate), air :!! (Window. runtime), query :!! (Document. queryselector )},
Plugins :{},
Engines :{
Presto: function (){
Return (! Window. Opera )? False: (arguments. callee. Caller )? 960: (document. getelementsbyclassname )? 950: 925 ));
},
Trident: function (){
Return (! Window. activexobject )? False: (window. XMLHttpRequest )? (Document. queryselectorall )? 6: 5): 4 );
},
WebKit: function (){
Return (navigator. taintenabled )? False: (browser. features. XPath )? (Browser. features. query )? 525: 420): 419 );
},
Gecko: function (){
Return (! Document. getboxobjectfor & window. Fig = NULL )? False: (document. getelementsbyclassname )? 19: 18 );
}
}
}, Browser | {});
What should I do?
Feature Detection is a method that should be avoided, although direct feature detection is a good method that can meet requirements in most cases. Generally, you only need to know whether this feature is implemented before detection, without considering the relationship between them.
I do not mean that browser feature detection is never used, but based on UA sniffing, because I believe it still has many purposes, but I do not believe it has many reasonable uses. If you consider UA sniffing, first implement this idea: the only safe way is for a specific version of a specific browser, out of scope is not reliable-such as a new browser version. In fact, this is also a wise way to do this, because backward compatibility with the old version is the simplest practice compared to the new version with backward compatibility uncertainty.