兼容性汇总
不管是学到的,还是工作上遇到的,都记录。一直更新,直到不做前端为止。
灰色字是例子。
JS相关
1,Object.defineProperty
Object.defineProperty(obj, "name", {
get: function(){return "给力叔"},
enumerable: true,
configurable: true
});
Internet Explorer 9 标准模式、Internet Explorer 10 标准模式以及 Windows 8.x 应用商店 应用支持所有功能。
Internet Explorer 8 标准模式 支持 DOM 对象,但不支持用户定义的对象。可以指定 enumerable 和 configurable 特性,但不使用它们。
2,Object.create(prototype, descriptors),创建一个具有指定原型且可选择性地包含指定属性的对象。
IE6,7,8不支持
3,Object.assign(target, ...sources );将来自一个或多个源对象中的值复制到一个目标对象。
IE10 且edge才支持,这货没得救了,基本是自己写一个的节奏。
4,Object.definePropertys.将一个或多个属性添加到对象,并/或修改现有属性的特性。
Object.defineProperties(obj, { size: { name: "", writable: true, enumerable: true, configurable: true }
}
IE9与IE9+支持
5,Object.keys(object).返回对象的可枚举属性和方法的名称。不包括原型链的。
IE8+
例子:
function Class (){ this.a = "a"; this.b = "b"; this.c = function(){ } } Class.prototype.d = function(){ } console.log(Object.keys(new Class()).toString()); //a,b,c
6,object.constructor.指定创建一个对象的函数。
IE5+,终于看到个兼容性杠杠的。
7,object.hasOwnProperty(proName)。确定某个对象(不包括原型链)是否具有带指定名称的属性。
IE5+。
8,Object.getOwnPropertyNames.返回对象自己的属性的名称。一个对象的自己的属性是指直接对该对象定义的属性,而不是从该对象的原型继承的属性。对象的属性包括字段(对象)和函数。
IE8+,cocos2djs类库用到它。
9,Object.getPrototypeOf。返回对象的原型。
IE8+
替代方案
function Uncle (){ } var uncle = new Uncle() console.log(Object.getPrototypeOf(uncle) === Uncle.prototype); //true console.log(Uncle.prototype === uncle.constructor.prototype); //true
BOM相关.
IE < 9删除全局变量会出错.例如:delete window.age;
IOS高版本,window.open会出错.估计是被屏蔽了。
IE8修改window.location.hash会产生一条浏览记录。
检查插件,非IE浏览器通过遍历navigator.plugins检查,IE使用new ActiveObject();
function hasPlugin(pluginName,iePluginName){ pluginName = pluginName.toLowerCase(); var result; for(var i = 0,plugin;plugin = navigator.plugins[i];i++){ if(plugin.name.toLowerCase().indexOf(pluginName) != -1){ result = true; } } if(!result){//没有就检查IE的 try{ new ActiveXObject(iePluginName); result = true; return result; }catch(e){ return result; } }else{ return result; } }
DOM相关
获取scrollTop...
页面具有 DTD,或者说指定了 DOCTYPE 时,使用 document.documentElement。
页面不具有 DTD,或者说没有指定了 DOCTYPE,时,使用 document.body。
在 IE 和 Firefox 中均是如此。
为了兼容,不管有没有 DTD,可以使用如下代码:
var scrollTop = window.pageYOffset //用于FF || document.documentElement.scrollTop || document.body.scrollTop || 0;
获取最终样式.
alert((element.currentStyle? element.currentStyle : window.getComputedStyle(element, null)).height);
获取styleSheet中的所有cssRules.假设要获取第一个的。
var sheet = document.styleSheets[0], rules = sheet.cssRules || sheet.rules;
动态创建script节点.
var script = document.createElement("script"), code = "function(){}", text; script.type = "text/javascript"; try{ text = document.createTextNode(code);//IE会报错。。。 script.appendChild(text); }catch(e){ script.text = code; }
class和className兼容方法:
object.setAttribute("class","content")
在IE8、Chrome、火狐、Opera10中都能设置成功;但是在IE7下无法设置。
object.setAttribute("className","content")
只有IE7能设置成功,但是其他浏览器均无法设置。
兼容方法:
使用 object.className="content"
style和cssText兼容方法:
object.setAttribute("style","position:absolute;left:10px;top:10px;")
在IE8、Chrome、火狐、Opera10中都能设置成功;但是在IE7下无法设置。
object.setAttribute("cssText","position:absolute;left:10px;top:10px;")
此设置方法,所有浏览器均不支持。
兼容方法:
使用 object.style.cssText="position:absolute;left:10px;top:10px;"
或者单独 object.style.各个属性 ,逐一进行设置。
IE7及以下,getAttribute("style")和getAttribute("onclick")返回值和属性值相同。
IE7及更早someNode.attributes会返回所有可能的特性。可以通过someNode.attributes[0].specifed判断是不是特性。
IE6不支持removeAttribute
IE7及更早版本,不能动态设置iframe.name,button.type = "reset"和name相同的单选按钮是无关系的。
IE8及IE8以下的浏览器,NodeList实现为com对象,不能使用Array.prototype.slice.call转换成数组.因为会报错。
function convertNodeListToArray(nodeList){ var array = null; try{ array = Array.prototype.slice.call(nodeList,0); }catch(e){ array = []; for(var i = 0,element;element = nodeList[i];i++){ array.push(element); } } return array; }
firstElementChild,lastElementChild,IE9+才支持。做H5开发直接可以拿来爽哦。
IE8及更早,children会包含注释节点.
<video>
手机端不支持自动播放,不支持自动缓存。安卓端不支持取消控制栏。
<svg>
手机端:内容丰富的svg在换页的时候可能会黑屏。
innerText
IE、Safari、Opera和Chrome支持innerText属性。Firefox虽然不支持innerText,但支持作用类似的textContent属性。textContent是DOM3级规定的一个属性,而且也得到了safari、opera和Chrome的支持。
dragable:
IE10+,FireFox 4+,Safari 5+,Chrome,Opera 11.5与之前都不支持。
obj.ownerDocument.createDocumentFragment(from jq)
这样调用在谷歌或者火狐浏览器会报错,使用document.createDocumentFragment
getElementById(from jq)
IE6,7或者部分opera浏览器有时候会使用名称进行匹配搜索。例如:<meta name="test">,document.getElementById("test");会获取到meta标签。
IE6在fragment中放入embed,script,object,option,style等标签会报错(from jq:1.7.1-6105)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>测试embed标签放入fragment</title> </head> <body> <script type="text/javascript"> try{ var frag = document.createDocumentFragment(); var embed = document.createElement("embed"); frag.appendChild(embed); embed.innerText = "ss"; document.body.appendChild(frag); }catch(e){ alert(e.message); } </script> </body> </html>
克隆options的时候,会丢失selected状态(from jq:1.7.1-6104)
webkit内核的浏览器克隆对象的时候会丢失checked等属性(from jq:1.7.1-6106)
IE低版本使用clonenode的时候会克隆事件处理程序。
IE6/7中,input被appendChild之后,checked属性会丢失(from jq:1.7.1-1466)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title></title> </head> <body> <script type="text/javascript"> try{ var input = document.createElement("input"); input.type = "checkbox"; input.checked = true; alert(input.checked); //true document.body.appendChild(input); alert(input.checked) //false }catch(e){ alert(e.message); } </script> </body> </html>
IE9以下,将<link rel="stylesheet" type="text/css" href="test.css"/>放到div.innerHTML中无效.
可以改成,<div><link rel="stylesheet" type="text/css" href="test.css"/></div>后,再放到放到div.innerHTML
IE9以下不会自动识别,article,footer等标签,当把article设置到innerHTML的时候,会创建一个不包含子节点的空元素,解决办法就是createElement,教会浏览器。(from jq:1.7.1-5628,createSafeFragment)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>测试插入footer插入到innerHTML</title> </head> <body> <script type="text/javascript"> var div = document.createElement("div"); div.innerHTML = "<footer></footer>"; alert(div.childNodes[0]);//在IE6,undefined。谷歌浏览器下是存在的。 </script> </body> </html>
IE6/7设置table进入innerHTML中的时候,会为table创建tbody标签.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>测试IE6/7会不会自动生成tbody</title> </head> <body> <script type="text/javascript"> var div = document.createElement("div"); div.innerHTML = "<table></table>"; alert(div.firstChild.firstChild); //[object Object],谷歌浏览器是null </script> </body> </html>
IE6设置innerHTML的时候,会自动删除开头的空格
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>IE6设置innerHTML的时候,会自动删除开头的空格</title> </head> <body> <script type="text/javascript"> var div = document.createElement("div"); div.innerHTML = " <a></a>"; var reg = /^(\s+)/; alert(reg.exec(div.innerHTML)[0].length);//IE6报错,谷歌是5. </script> </body> </html>
stringObj[index],IE7+才支持,IE7及IE7以下使用chatAt
在IE6/7不移除字符串的头尾有换行符的情况下,new Function('return ' + ' \n{} ')不能正常解析
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>IE6,7字符串开始有换行符的情况下不能正常解析</title> </head> <body> <script type="text/javascript"> document.write(new Function("return \n{}")()); </script> </body> </html>
解析XML,正常情况下使用DOMParser,IE9-使用ActiveXObject( "Microsoft.XMLDOM" )
parseXML: function( data ) {
var xml, tmp;
try {
if ( window.DOMParser ) { // Standard,IE9+
tmp = new DOMParser();
xml = tmp.parseFromString( data , "text/xml" );
} else { // IE
xml = new ActiveXObject( "Microsoft.XMLDOM" );
xml.async = "false";
xml.loadXML( data );
}
} catch( e ) {
xml = undefined;
}
if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
jQuery.error( "Invalid XML: " + data );
}
return xml;
}
如果想让一段代码在全局域执行,from jq.
globalEval: function( data ) { if ( data && rnotwhite.test( data ) ) { ( window.execScript || function( data ) { window[ "eval" ].call( window, data );//直接eval会变成局部域,window[ "eval" ].call在IE6不能执行。。。
} )( data ); } }
delete全局变量,IE < 9都会报错,其他的浏览器按规范走。
var name = "大叔"; window.age = 99; //IE < 9会报错,其他浏览器返回false delete name; //IE < 9会报错,其他浏览器返回true delete age;
IE8之前,typeof document.createElement返回的是'object',不是"function".可以用以下函数判断函数属性.摘自Javascript 高级程序设计
function isHostMethod(object,property){ var ret = typeof object[property]; return ret == "function" || (!!(ret == "object" && object[property])) || ret == "unknown"; }
IE9以下的浏览器。正则表达式\s不能匹配\xA0。
IE8-浏览器的dom对象不是纯粹的js对象,会造成引用.影响内存回收.
Array.prototype.slice.call(NodeList,0)在IE8-会出错,可以使用循环把NodeList转成Array
移动端fiexd有问题
移动端,IE等,input框的readonly是个笑话