检测浏览器支持属性的工具
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>browserZ</title>
<script type="text/javascript">
var $init;
var notsure = {};
-function() {
var FUNS = [];
$init = function(f) {
FUNS.push(f);
};
window.onload = function(e) {
for (var i = 0; i < FUNS.length; i++)
FUNS[i](e);
}
} ();
var up = function(e, s) {
var el = document.getElementById(e);
if (el.tagName.toLowerCase() === 'span' && el.className === 'option')
el.innerHTML = s ? 'Yes' : 'No';
else
el.innerHTML = s;
}
var fields = function(en, data) {
var e = document.getElementById(en);
var s = '';
for (var each in data) {
if (typeof (data[each]) === 'string')
s += '<label>' + each + '<span>' + data[each] + '</span></label>/n';
else if (typeof (data[each]) === notsure)
s += '<label>' + each + '<span class="notsure">Not Sure</span></label>/n';
else
s += '<label>' + each + '<span class="bool ' + (data[each] ? 'true' : 'false') + '"><span>' + (data[each] ? 'Yes' : 'No') + '</span></span></label>/n';
}
e.innerHTML += s;
}
var brk = function(en){
document.getElementById(en).innerHTML += '<div class="break"></div>'
}
$init(function() {
var ua = navigator.userAgent, b;
up('ua', ua);
fields('uadetect', {
'is IE?': /msie/i.test(ua),
'is Firefox?': /firefox/i.test(ua),
'is WebKit?': /webkit/i.test(ua),
'is Chrome?': /chrome/i.test(ua),
'is Safari?': /safari/i.test(ua),
'is Opera?': /opera/i.test(ua)
});
up('uaresult', 'You/'re using ' + (b = function() {
return /opera/i.test(ua) ? 'Opera'
: /firefox/i.test(ua) ? 'Firefox'
: /chrome/i.test(ua) ? 'Chrome'
: /safari/i.test(ua) ? 'Safari'
: /msie/i.test(ua) ? 'Internet Explorer'
: /gecko/i.test(ua) ? 'Other Gecko'
: /webkit/i.test(ua) ? 'Other Webkit'
: 'Other browser';
} ()));
brk('uadetect');
fields('uadetect', function() {
switch (b) {
case 'Internet Explorer':
{
return {
Engine: 'Trident',
'JScript Version': (0/*@cc_on + ScriptEngineMajorVersion() + 0.1 * ScriptEngineMinorVersion()@*/).toFixed(1)
}
}
case 'Firefox': case 'Other Gecko':
{
return {
Engine: 'Gecko'
}
}
case 'Chrome': case 'Safari': case 'Other Gecko':
{
return {
Engine: 'Webkit'
}
}
}
} ());
fields('uadetect', {
'Engine Version': ((navigator.userAgent.toLowerCase()).match(/.+(?:rv|webkit|opera|msie)[//: ]([/d.]+)/) || [0, '0'])[1]
});
up('hfresult', function() {
var fs = ['XML', '1.0',
'HTML', '1.0',
'Core', '2.0',
'XML', '2.0',
'HTML', '2.0',
'Views', '2.0',
'StyleSheets', '2.0',
'CSS', '2.0',
'CSS2', '2.0',
'Events', '2.0',
'UIEvents', '2.0',
'MutationEvents', '2.0',
'HTMLEvents', '2.0',
'Range', '2.0',
'Traversal', '2.0'], ans = [];
for (var i = 0; i < fs.length; i += 2) {
if (document.implementation.hasFeature(fs[i], fs[i + 1]))
ans.push(fs[i] + ' ' + fs[i + 1]);
};
return ans.join(' , ');
} ());
});
$init(function() {
fields('ecmadt', {
'Conditional Compile': /*@cc_on!@*/!1,
'//v support': '/v' != 'v',
'Ignore commas in the end of Arraies': [1, ].toString() == '1',
'Detect property enumerability by property name': function() { var obj = {}; obj.toString = function() { return '.' }; for (var each in obj) { return false }; return true; } (),
'__proto__ support': !!({}.__proto__),
'__scope__ support': typeof ({}.__scope__) !== 'undefined',
'__parent__ support': typeof ({}.__parent__) !== 'undefined'
});
fields('es5misc', {
'Strict Mode': function() {
try {
(function() {
"use strict"
eval = null;
arguments = null;
NOT_EXIST = null;
} ());
} catch (e) {
return true;
}
return false;
} (),
'Native JSON': !!window.JSON,
'Date.now': !!Date.now,
'Date toISOString': !!Date.prototype.toISOString,
'String trim': !!String.prototype.trim,
'Function bind': !!Function.prototype.bind
});
fields('getset', function() {
var x = {}, getact = false, setact = false;
try {
Object.defineProperty(x, 'p', {
get: function() { getact = true }, set: function(v) { setact = (v === 1) }
});
} catch (e) {
return {
Support: false
}
};
var v = x.p;
x.p = 1;
return {
'Getter': getact,
'Setter': setact
}
} ());
fields('es5objst', { 'Object.defineProperty': !!Object.defineProperty,
'Object.defineProperty on native objects': function() {
try {
Object.defineProperty({}, 'p', {
get: function() { }, set: function() { }
});
} catch (e) {
return false;
}
return true
} (),
'Object.getOwnPropertyDescriptor': !!Object.getOwnPropertyDescriptor,
'Object.getOwnPropertyNames': !!Object.getOwnPropertyNames,
'Object.create': !!Object.create,
'Object.getPrototypeOf': !!Object.getPrototypeOf,
'Object.keys': !!Object.keys,
'Object.seal': !!Object.seal,
'Object.freeze': !!Object.freeze
});
fields('es5arr', {
'Array.isArray': !!Array.isArray,
'Array indexOf': !![].indexOf,
'Array lastIndexOf': !![].lastIndexOf,
'Array map': !![].map,
'Array filter': !![].filter,
'Array reduce': !![].reduce,
'Array reduceRight': !![].reduceRight,
'Array every': !![].every,
'Array some': !![].some,
'Array forEach': !![].forEach
});
});
$init(function() {
fields('esenv', {
'execScript': !!window.execScript,
'setInterval' : !!window.setInterval,
'setTimeout' : !!window.setTimeout
});
});
$init(function(e) {
var b = document.body;
fields('domevent', {
'addEventListener': b.addEventListener ? true : (b.attachEvent ? 'as <code>attachEvent</code>' : false),
'removeEventListener': b.removeEventListener ? true : (b.detachEvent ? 'as <code>detachEvent</code>' : false),
'passing <code>event</code> object as argument': typeof e !== 'undefined' ? true : (window.event ? 'as <code>window.event</code>' : false)
});
brk('domevent');
-function() {
var br = function() { brk('domevent') };
var isEventSupported = (function() {
var win = window, cache = {}, TAGNAMES = {
'select': 'input', 'change': 'input',
'submit': 'form', 'reset': 'form',
'error': 'img', 'load': 'img', 'abort': 'img'
};
return function(eventName) {
var key = (TAGNAMES[eventName] || (eventName == "unload" || eventName == "resize") ? "window" : 'div') + "_" + eventName;
if (cache[key]) return cache[key];
var el = document.createElement(TAGNAMES[eventName] || 'div');
var oneventName = 'on' + eventName.toLowerCase();
// this test should work in most cases apart from IE/Webkit with unload/resize
var isSupported = (oneventName in el);
// we cannot use createElement to create a window object so to get a correct test for IE/Webkit on resize/unload check the window
if (!isSupported && (eventName == "unload" || eventName == "resize")) {
isSupported = (oneventName in win);
}
// fallback to setAttribute if supported
if (!isSupported && el.setAttribute) {
el.setAttribute(oneventName, 'return;');
isSupported = typeof el[oneventName] == 'function';
}
// the above tests should work in majority of cases but this test checks the EVENT object
// haven't seen an example where this is required yet so may not be required
if (!isSupported && win.Event && typeof (win.Event) == "object") {
isSupported = (eventName.toUpperCase() in win.Event);
}
el = null;
cache[key] = isSupported;
return isSupported;
}
} ());
function w(name, element) {
var x = {};
x['<code>' + name + '</code> event'] = isEventSupported(name, element);
fields('domevent', x);
};
setTimeout(function() {
w('click');
w('dblclick');
w('mousedown');
w('mouseup');
w('mouseover');
w('mousemove');
w('mouseout');
br();
w('keypress');
w('keydown');
w('keyup');
br();
w('load');
w('unload', window);
w('abort');
w('error');
}, 10);
setTimeout(function() {
br();
w('resize', window);
w('scroll');
br();
w('submit');
w('reset');
br();
w('select');
w('change');
br();
w('focus');
w('blur');
br();
w('cut');
w('copy');
w('paste');
}, 20);
setTimeout(function() {
w('beforecut');
w('beforecopy');
w('beforepaste');
w('afterupdate');
w('beforeupdate');
w('cellchange');
w('dataavailable');
w('datasetchanged');
w('datasetcomplete');
w('errorupdate');
w('rowenter');
w('rowexit');
w('rowsdelete');
w('drag');
w('dragstart');
w('dragenter');
w('dragover');
w('dragleave');
w('dragend');
w('drop');
w('selectstart');
w('mouseenter');
w('mouseleave');
w('activate');
w('beforeactivate');
w('deactivate');
w('beforedeactivate');
w('focusin');
w('focusout');
w('stop', document);
w('readystatechange');
w('beforeprint', document.body);
w('afterprint', document.body);
w('beforeunload', window);
}, 30);
setTimeout(function() {
br();
w('contextmenu');
br();
w('touchstart');
w('touchend');
w('touchmove');
w('touchcancel');
br();
w('gesturestart');
w('gesturechange');
w('gestureend');
br();
w('hashchange', document.body);
w('online', document.body);
w('offline', document.body);
w('message', window);
w('undo', document.body);
w('redo', document.body);
w('storage', window);
w('popstate', window);
w('canplay', document.createElement('video'));
w('seeking', document.createElement('video'));
w('seekend', document.createElement('video'));
br();
w('pageshow', window);
w('pagehide', window);
}, 50);
} ();
fields('html5', {
'<canvas>': !!document.createElement('canvas').getContext,
'<canvas> Text': function() {
if (!document.createElement('canvas').getContext) { return false; }
var dummy_canvas = document.createElement('canvas');
var context = dummy_canvas.getContext('2d');
return typeof context.fillText == 'function';
} (),
'<video>': !!document.createElement('video').canPlayType,
'<input> placeholder': function() {
var i = document.createElement('input');
return 'placeholder' in i;
} (),
'<input> autofocus': function() {
var i = document.createElement('input');
return 'autofocus' in i;
} (),
'Local Storage': !!window.localStorage,
'Session Storage': !!window.sessionStorage,
'Web worker': !!window.Worker,
'Offline application': !!window.applicationCache,
'GeoLocation': !!navigator.geolocation,
'Microdata': !!document.getItems
});
});
</script>
<style>
html{
font-family:Segoe UI, sans-serif;
background:white;
}
@media screen{
body{
width:540px;
margin:auto;
padding:1px 6px;
border-left:1px solid #e5e5e5;
border-right:1px solid #bbb;
background:#eee;
}
}
fieldset{
line-height:1.5;
padding:0.3em 0 0.3em 0.3em;
margin-right:0;
border:none;
border-left:2px solid #ccc;
border-top:2px solid #ddd;
}
legend{
color:#039
}
label{
margin:0 1em;
white-space:nowrap;
}
label span,div.longinfo{
background:#fff;
border:1px inset #ccc;
padding:0 0.4em;
margin-left:0.5em;
}
div.longinfo{
margin-bottom:0.4em;
}
div.break{
border-top:1px solid #aaa;
border-bottom:1px solid #fff;
margin:0.3em 0;
}
label span span{
border:none;
background:none;
margin:0;
padding:0
}
label span.true{
background:green;
color:White;
border-color:gree.;
}
label span.false{
background:darkred;
color:White;
border-color:darkred;
}
fieldset.wide label{
display:block;
text-align:right;
margin:0 10em 0 0;
position:relative;
}
fieldset.wide label span{
display:block;
position:absolute;
left:100%;
top:1px;
bottom:1px;
width:auto;
height:auto;
line-height:1.3em;
width:8.6em;
text-align:left;
border:none;
}
* html fieldset.wide label span{
left:auto;
top:0;
}
fieldset.wide label span span{
display:inline;
position:static;
width:auto;
}
#css span{
background:darkred;
color:White;
}
#css span.cover{
background:none;
}
#cssselectors #childsel>span{background:green;}
#cssselectors #siblingsel b+span{background:green;}
#cssselectors #siblingsel2 b~span{background:green;}
#cssselectors [lang] span{background:green;}
#cssselectors [id=propeq] span{background:green;}
#cssselectors [rel~=a] span{background:green;}
#cssselectors [rel|=abc] span{background:green;}
#cssselectors [rel*=iabc] span{background:green;}
#cssselectors [rel$=defk] span{background:green;}
#cssselectors [rel*=cyd] span{background:green;}
html:root #cssselectors #rootsel span{background:green}
#cssselectors #nthchild span:nth-child(1){background:green}
#cssselectors #nthlchild span:nth-last-child(1){background:green}
#cssselectors #nthot span:nth-of-type(1){background:green}
#cssselectors #nthlot span:nth-last-of-type(1){background:green}
#cssselectors #isempty span:empty{background:green}
#css3fes #rgba span.cover{background:rgba(0,128,0,1)}
#css3fes #hsl span.cover{background:hsl(120,100%,25%)}
#css3fes #hsla span.cover{background:hsla(120,100%,25%,1)}
#css3fes #transf span{background:green}
#css3fes #transf span.cover{background:darkred;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0)}
</style>
</head>
<body>
<h1>browser-Z 0.0.1</h1>
<h2>corodidea.net powered</h2>
<noscript>
Browser-Z requires a javascript-enabled user agent. Please enable JavaScript to enable browser-Z.
</noscript>
<fieldset>
<legend>Browser Information</legend>
<fieldset id="uainfo">
<legend>User Agent</legend>
<div class="longinfo" id="ua"></div>
</fieldset>
<fieldset id="uadetect">
<legend>Detecting by User Agent</legend>
<div class="longinfo" id="uaresult"></div>
</fieldset>
<fieldset>
<legend>hasFeature results</legend>
<div id="hfresult" class="longinfo"></div>
</fieldset>
</fieldset>
<fieldset id="css" class="wide">
<legend>CSS support</legend>
<div class="longinfo">Note that in this section the green box means "test succeed"</div>
<fieldset id="cssselectors">
<legend>Advanced Selectors</legend>
<label id="childsel">> <span></span></label>
<label id="siblingsel">+ <b></b><span></span></label>
<label id="siblingsel2">~ <b></b><i></i><span></span></label>
<label id="propexist" lang="en">Property - Existance <span></span></label>
<label id="propeq">Property - Equal <span></span></label>
<label id="propsp" rel="a b-a ca">Property - Space <span></span></label>
<label id="propdp" rel="abc-def">Property - Dash <span></span></label>
<label id="propst" rel="iabcxdefj">Property - Start <span></span></label>
<label id="proped" rel="kabcxdefk">Property - End <span></span></label>
<label id="proppt" rel="labcydefl">Property - Part <span></span></label>
<label id="rootsel">:root <span></span></label>
<label id="nthchild">:nth-child <span></span></label>
<label id="nthlchild">:nth-last-child <span></span></label>
<label id="nthot">:nth-of-type <span></span></label>
<label id="nthlot">:nth-last-of-type <span></span></label>
<label id="isempty">:empty <span></span></label>
</fieldset>
<fieldset id="css3fes">
<legend>CSS3 features</legend>
<label id="rgba">rgba <span></span><span class="cover"></span></label>
<label id="hsl">hsl <span></span><span class="cover"></span></label>
<label id="hsla">hsla <span></span><span class="cover"></span></label>
<label id="transf">CSS Transform <span></span><span class="cover"></span></label>
</fieldset>
</fieldset>
<fieldset class="wide" id="eslang">
<legend>ECMAScript features</legend>
<fieldset id="ecmadt">
<legend>ECMA Detailed Support</legend>
</fieldset>
<fieldset id="ecma5">
<legend>ECMA v5 Detailed Support</legend>
<fieldset id="getset">
<legend>Getters and Setters</legend>
</fieldset>
<fieldset id="es5objst">
<legend>Object static methods</legend>
</fieldset>
<fieldset id="es5arr">
<legend>Array extensions</legend>
</fieldset>
<fieldset id="es5misc">
<legend>Misc</legend>
</fieldset>
</fieldset>
<fieldset class="wide" id="esenv">
<legend>ECMAScript environment</legend>
</fieldset>
</fieldset>
<fieldset class="wide" id="dom">
<legend>DOM support</legend>
<fieldset id="domevent">
<legend>DOM Event Support</legend>
</fieldset>
<fieldset id="html5">
<legend>HTML5 Features</legend>
</fieldset>
</fieldset>
</body>
</html>