简要教程
Feature.js是一款轻量级的浏览器特性检测JavaScript库插件。该插件运行速度快,使用简单,文件只有1kb大小。通过Feature.js你可以检测客户浏览器是否支持某些特性,并针对这些特性编写代码。
Feature.js会自动在页面初始化时进行加载,但是它不会自动进行特性检测,直到你在代码中调用它时才会进行指定特性的检测。
通过Feature.js你可以对浏览器进行特性检测,例如检测浏览器是否支持CSS 3D transforms,为支持该特性的浏览器编写代码来操纵元素进行3D转换,在不支持该特性的浏览器中可以执行其他的操作。
使用方法
首先你需要在页面中引入feature.js文件,你不需要对其进行初始化,只需引入文件即可。
<script src="js/feature.js"></script>
接着你就可以使用特性检测来检测浏览器是否支持某些特性,例如:
if (feature.webGL) { console.log("你的浏览器支持WebGL"); } else { console.log("你的浏览器不支持WebGL"); }
如果你希望像Modernizr那样当浏览器支持某些特性时,在<html>元素上添加相应的class,可以像下面这样操作:
if (feature.webGL) { document.documentElement.className += " webgl"; }
如果你使用jquery,那操作就更简单了:
if (feature.webGL) { $("html").addClass("webgl"); }
你也可以同时进行多选特性的检测:
if (feature.canvas && feature.webGL) { console.log("你的浏览器支持Canvas和WebGL") }
如果你的JavaScript代码只有在浏览器支持某些特性时才有意义,那么你可以在一个函数中检测这些特性,如果浏览器不支持这些特性,直接返回,否则才执行相应的JS代码。
(function() { if (!feature.webGL || !feature.svg) { console.log("Stopping… WebGL or SVG isn’t supported"); return; } console.log("Browser supports both WebGL & SVG"); })();
API reference
下面是Feature.js可进行的浏览器检测的特性列表。
- feature.async
- feature.addEventListener
- feature.canvas
- feature.classList
- feature.cors
- feature.contextMenu
- feature.css3Dtransform
- feature.cssTransform
- feature.cssTransition
- feature.defer
- feature.deviceMotion
- feature.deviceOrientation
- feature.geolocation
- feature.historyAPI
- feature.placeholder
- feature.localStorage
- feature.matchMedia
- feature.pictureElement
- feature.querySelectorAll
- feature.remUnit
- feature.serviceWorker
- feature.sizes
- feature.srcset
- feature.svg
- feature.touch
- feature.viewportUnit
- feature.webGL
Feature.js浏览器特性检测插件的github地址为:https://github.com/viljamis/feature.js
附源码:
/*! | |
* FEATURE.JS 1.0.1, A Fast, simple and lightweight browser feature | |
* detection library in just 1kb. | |
* | |
* http://featurejs.com | |
* | |
* CSS 3D Transform, CSS Transform, CSS Transition, Canvas, SVG, | |
* addEventListener, querySelectorAll, matchMedia, classList API, | |
* placeholder, localStorage, History API, Viewport Units, REM Units, | |
* CORS, WebGL, Service Worker, Context Menu, Geolocation, | |
* Device Motion, Device Orientation, Touch, Async, Defer, | |
* Srcset, Sizes & Picture Element. | |
* | |
* | |
* USAGE EXAMPLE: | |
* if (feature.webGL) { | |
* console.log("webGL supported!"); | |
* } | |
* | |
* Author: @viljamis, https://viljamis.com | |
*/ | |
/* globals DocumentTouch */ | |
;(function (window, document, undefined) { | |
"use strict"; | |
// For minification only | |
var docEl = document.documentElement; | |
/** | |
* Utilities | |
*/ | |
var util = { | |
/** | |
* Simple create element method | |
*/ | |
create : function(el) { | |
return document.createElement(el); | |
}, | |
/** | |
* Test if it's an old device that we want to filter out | |
*/ | |
old : !!(/(Androids(1.|2.))|(Silk/1.)/i.test(navigator.userAgent)), | |
/** | |
* Function that takes a standard CSS property name as a parameter and | |
* returns it's prefixed version valid for current browser it runs in | |
*/ | |
pfx : (function() { | |
var style = document.createElement("dummy").style; | |
var prefixes = ["Webkit", "Moz", "O", "ms"]; | |
var memory = {}; | |
return function(prop) { | |
if (typeof memory[prop] === "undefined") { | |
var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1), | |
props = (prop + " " + prefixes.join(ucProp + " ") + ucProp).split(" "); | |
memory[prop] = null; | |
for (var i in props) { | |
if (style[props[i]] !== undefined) { | |
memory[prop] = props[i]; | |
break; | |
} | |
} | |
} | |
return memory[prop]; | |
}; | |
})() | |
}; | |
/** | |
* The Feature.js object | |
*/ | |
var Feature = { | |
// Test if CSS 3D transforms are supported | |
css3Dtransform : (function() { | |
var test = (!util.old && util.pfx("perspective") !== null); | |
return !!test; | |
})(), | |
// Test if CSS transforms are supported | |
cssTransform : (function() { | |
var test = (!util.old && util.pfx("transformOrigin") !== null); | |
return !!test; | |
})(), | |
// Test if CSS transitions are supported | |
cssTransition : (function() { | |
var test = util.pfx("transition") !== null; | |
return !!test; | |
})(), | |
// Test if addEventListener is supported | |
addEventListener : !!window.addEventListener, | |
// Test if querySelectorAll is supported | |
querySelectorAll : !!document.querySelectorAll, | |
// Test if matchMedia is supported | |
matchMedia : !!window.matchMedia, | |
// Test if Device Motion is supported | |
deviceMotion : ("DeviceMotionEvent" in window), | |
// Test if Device Orientation is supported | |
deviceOrientation : ("DeviceOrientationEvent" in window), | |
// Test if Context Menu is supported | |
contextMenu : ("contextMenu" in docEl && "HTMLMenuItemElement" in window), | |
// Test if classList API is supported | |
classList : ("classList" in docEl), | |
// Test if placeholder attribute is supported | |
placeholder : ("placeholder" in util.create("input")), | |
// Test if localStorage is supported | |
localStorage : (function() { | |
var test = "x"; | |
try { | |
localStorage.setItem(test, test); | |
localStorage.removeItem(test); | |
return true; | |
} catch(err) { | |
return false; | |
} | |
})(), | |
// Test if History API is supported | |
historyAPI : (window.history && "pushState" in window.history), | |
// Test if ServiceWorkers are supported | |
serviceWorker : ("serviceWorker" in navigator), | |
// Test if viewport units are supported | |
viewportUnit : (function(el) { | |
try { | |
el.style.width = "1vw"; | |
var test = el.style.width !== ""; | |
return !!test; | |
} catch(err) { | |
return false; | |
} | |
})(util.create("dummy")), | |
// Test if REM units are supported | |
remUnit : (function(el) { | |
try { | |
el.style.width = "1rem"; | |
var test = el.style.width !== ""; | |
return !!test; | |
} catch(err) { | |
return false; | |
} | |
})(util.create("dummy")), | |
// Test if Canvas is supported | |
canvas : (function(el) { | |
return !!(el.getContext && el.getContext("2d")); | |
})(util.create("canvas")), | |
// Test if SVG is supported | |
svg : !!document.createElementNS && !!document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGRect, | |
// Test if WebGL is supported | |
webGL : (function(el) { | |
try { | |
return !!(window.WebGLRenderingContext && (el.getContext("webgl") || el.getContext("experimental-webgl"))); | |
} catch(err) { | |
return false; | |
} | |
})(util.create("canvas")), | |
// Test if cors is supported | |
cors : ("XMLHttpRequest" in window && "withCredentials" in new XMLHttpRequest()), | |
// Tests if touch events are supported, but doesn't necessarily reflect a touchscreen device | |
touch : !!(("ontouchstart" in window) || window.navigator && window.navigator.msPointerEnabled && window.MSGesture || window.DocumentTouch && document instanceof DocumentTouch), | |
// Test if async attribute is supported | |
async : ("async" in util.create("script")), | |
// Test if defer attribute is supported | |
defer : ("defer" in util.create("script")), | |
// Test if Geolocation is supported | |
geolocation : ("geolocation" in navigator), | |
// Test if img srcset attribute is supported | |
srcset : ("srcset" in util.create("img")), | |
// Test if img sizes attribute is supported | |
sizes : ("sizes" in util.create("img")), | |
// Test if Picture element is supported | |
pictureElement : ("HTMLPictureElement" in window), | |
// Run all the tests and add supported classes | |
testAll : function() { | |
var classes = " js"; | |
for (var test in this) { | |
if (test !== "testAll" && test !== "constructor" && this[test]) { | |
classes += " " + test; | |
} | |
} | |
docEl.className += classes.toLowerCase(); | |
} | |
}; | |
/** | |
* Expose a public-facing API | |
*/ | |
window.feature = Feature; | |
}(window, document)); |