Key Points
Once upon a time, browser detection was the best skill of JavaScript programmers. If we know that some features work in IE5 but not in Netscape 4, we will test the browser and modify the code accordingly. For example:
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
But when I first joined the industry, the arms race had already begun! Vendors are adding extra values to user agent strings, so they look like their competitors’ browsers, and their own. For example, this is Safari 5 for Mac:
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
This will match tests for "Safari", "Webkit", and "KHTML" (the Konqueror code base that Webkit is based); but it also matches "Gecko" (which is Firefox's rendering engine), and of course "Mozilla" ” (For historical reasons, almost every browser claims to be Mozilla).
The purpose of adding all these values is to circumvent browser detection. If the script assumes that only Firefox can handle specific features, Safari may be excluded, even if it may work. Don't forget that users can change their user agent themselves - I used to set my browser to recognize "Googlebot/1.0" so that I can access what the site owner thinks is for crawling only!
So, over time, this kind of browser detection has become an impossible mess and is largely out of use, replaced by something better—feature detection.
Feature detection is just to test the features we want to use. For example, if we need getBoundingClientRect
(get the position of an element relative to the viewport), then it is important whether the browser supports it, not which browser it is; therefore, instead of testing supported The browser is worse than the test feature itself:
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
But the truth is - feature detection is not entirely reliable - sometimes it fails. So let's look at some examples now and see what we can do to solve each case.
Perhaps the most famous example of feature detection failure is testing ActiveXObject for Ajax requests in Internet Explorer.
ActiveX is an example of late-bound objects, and the practical significance is that you can't know if it is supported until you try to use it . Therefore, if the user disables ActiveX, the following code will throw an error:
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
try instantiate the object, catch any failures and handle it accordingly:
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
supports draggable API by looking for draggable properties: [draggable="true"]
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
HTML properties to DOM properties. This is why is so confusing in these older versions, because it does not return properties at all, but DOM properties.
getAttribute
This means if we use an element that already has the
Then even if they are not supported, IE8 or earlier will return
forif (typeof window.ActiveXObject != "undefined") { var request = new ActiveXObject("Microsoft.XMLHTTP"); }
true
Attribute can be anything: ("draggable" in element)
But the result will be the same - IE8 or earlier will return
forif (typeof window.ActiveXObject != "undefined") { try { var request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ex) { request = null; } if (request !== null) { //... 我们有一个请求对象 } }
true
In this case, the solution is to use an element that does not have that attribute for testing, the safest way is to use the created element: ("nonsense" in element)
Assumptions about user behavior
if ("draggable" in element) { // 浏览器支持拖放 }
Most touch devices implement manual delays before triggering a click event (usually around 300 milliseconds), which is to avoid clicking on elements while also clicking them. But this makes the application feel sluggish and unresponsive, so developers sometimes use this feature test to fork the event:
<div draggable="true"> ... </div>
However, this condition stems from a
error of the<div nonsense="true"> ... </div>
In this case, the solution is not to test event support at all - instead bind two
events at the same time, and then use to prevent the touch from generating clicks: Acknowledging this is painful, but sometimes what we don't need to test is not the feature - but the browser - because a particular browser claims to support something that doesn't work. A recent example is Feature test fails here because Opera 12 claims to support it; exception handling is not helpful, either, because it does not throw any errors. It just doesn't work: Now, if you just want to try to add a custom drag image and are happy to keep the default value without support (which will happen), then this may be fine. But what if your application does need custom images so that browsers that do not support it should use a completely different implementation (i.e., use custom JavaScript to implement all drag behavior)?
object detection Opera 12 or earlier, so we can use this exclusion to test draggable support:
to determine support for specific features in a specific browser, or in case of emergency, define more precise browser conditions:
-the goal is to use browser conditions to exclude browsers because there is already Known errors, not include them because of known features (this is the purpose of feature testing)
Basically, always assume that the feature test is fully in line with - unless you know that this is not the case, then the feature will work as expected.
We were unable to use it in the past because IE5 and its similar products would throw errors due to syntax; but now we don't have to support these browsers, which is no longer a problem. Essentially, it's exactly the same as the following, but it's shorter to write: However, test conditions usually rely on automatic type conversion: We used this syntax earlier in some browser object tests (e.g. But we may be testing something that effectively returns null or empty strings, both of which evaluate to false. For example, the It will only evaluate to true if the The general rule is this: Relying on automatic type conversion is safe for objects and functions, but not necessarily safe for strings and numbers or values that may be null. That being said - if you can use it safely, do it because it is usually much faster in modern browsers (probably because they are optimized for this type of condition). For more information on this, see: Automatic Type Conversion in the Real World. JavaScript feature detection is a technology used by developers to determine whether a user's browser supports a specific feature or API. This is crucial because not all browsers support all features of JavaScript. By using feature detection, developers can provide alternative solutions or fallbacks for unsupported features, ensuring that websites or applications run correctly on different browsers. This enhances the user experience and ensures compatibility. JavaScript feature detection may fail for a number of reasons. A common reason is that the feature detection code is incorrectly implemented. For example, if the code checks for properties that do not exist in the object, it will return undefined, resulting in a false negative. Another reason could be a browser quirk or error, which could cause feature detection to give inaccurate results. Feature detection involves checking whether a user's browser supports a specific feature or API, while browser detection recognizes the user's browser and version. While both techniques are designed to ensure compatibility and functionality, feature detection is often considered a better practice because it checks for features directly, rather than assuming its support based on browser type or version. You can use the Feature.js is a lightweight, fast and simple JavaScript utility for feature detection. It provides an easy-to-use API that allows developers to test whether the browser supports specific features. This helps provide a backup solution or alternative solution for unsupported features, thereby enhancing compatibility and functionality of the website or application. Modernizr is a JavaScript library that helps developers take advantage of HTML5 and CSS3 features while maintaining compatibility with older browsers. It uses feature detection to check if the browser supports specific features and adds classes to HTML elements, allowing you to locate specific browser features in stylesheets or JavaScript. device-detector-js package is a powerful tool for device detection. It parses user agent strings and detects smartphones, tablets, desktops, TVs and other devices. It also detects browsers, engines, operating systems, and other useful information. You can use this package to adjust the behavior of a website or application based on the detected devices. Some best practices for implementing feature detection include: using reliable and tested libraries such as Modernizr or Feature.js, thoroughly testing your feature detection code on different browsers and devices, as unsupported Features provide alternative solutions or fallbacks and avoid assuming feature support based on browser type or version. Yes, feature detection can help improve website performance. By detecting unsupported features and providing alternative solutions or fallback solutions, you can prevent unnecessary code from running in the browser. This reduces load time and improves overall performance of the website. As a result of the rapid development of web development, it can be challenging to understand the latest features supported by different browsers. However, resources such as Mozilla Developer Network (MDN), Can I Use, and JavaScript documentation can provide the latest information on feature support in different browsers. The above is the detailed content of When JavaScript Feature Detection Fails. For more information, please follow other related articles on the PHP Chinese website!if (navigator.userAgent.indexOf('MSIE 5') != -1) {
// 我们认为此浏览器是 IE5
}
Things that don't work at all
setDragImage()
in Opera 12 (which is a way to drag and drop dataTransfer
objects). <code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
Prefer to proprietary object testing over navigator information.
For example, you can use window.opera
if (typeof document.documentElement.getBoundingClientRect != "undefined") {
// 浏览器支持此函数
}
if (typeof window.ActiveXObject != "undefined") {
var request = new ActiveXObject("Microsoft.XMLHTTP");
}
if (typeof window.ActiveXObject != "undefined") {
try {
var request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (ex) {
request = null;
}
if (request !== null) {
//... 我们有一个请求对象
}
}
if ("draggable" in element) {
// 浏览器支持拖放
}
if (navigator.userAgent.indexOf('MSIE 5') != -1) {
// 我们认为此浏览器是 IE5
}
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
if (typeof document.documentElement.getBoundingClientRect != "undefined") {
// 浏览器支持此函数
}
window.opera
tests), which is safe because of how objects evaluate - any defined object or function will always be evaluated as true, and if it is undefined, it will be evaluated as false. style.maxWidth
attribute is sometimes used to exclude IE6: if (typeof window.ActiveXObject != "undefined") {
var request = new ActiveXObject("Microsoft.XMLHTTP");
}
maxWidth
attribute is supported and the has the author defined value, so if we write the test like this, it may fail: if (typeof window.ActiveXObject != "undefined") {
try {
var request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (ex) {
request = null;
}
if (request !== null) {
//... 我们有一个请求对象
}
}
Frequently Asked Questions about JavaScript Feature Detection
What is JavaScript feature detection and why is it important?
How does JavaScript feature detection fail?
What is the difference between feature detection and browser detection?
How to use JavaScript to detect mobile devices?
navigator.userAgent
attribute in JavaScript to detect mobile devices. This property returns a string representing the browser's user agent header. By checking for specific keywords in this string (such as "Android", "iPhone", or "iPad"), you can determine if the user is on a mobile device. What is Feature.js and how does it help with feature detection?
What is Modernizr and how does it help with feature detection?
How to use the device-detector-js package for feature detection?
The What are some best practices for implementing feature detection?
Can feature detection help improve website performance?
How to understand the latest features supported by different browsers?