深入解析IE11中被废止的JS方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
深入解析IE11中被废止的方法
尽管我们已经了解了Internet Explorer 11中的一些新特性,包括对WebGL的支持、预抓取、预渲染、flexbox、mutation observers 以及其他一些Web标准的支持,特别是废弃了一些非标准的方法,这对一些较早开发的应用,产生了严重影响,甚至不能正常使用。
尽管可以使用IE11中的兼容性视图,但总是感觉不太理想。
至于到底有哪些变化,不经过实践验证,总是不能深入。
最近,因为项目需要,升级了前几年开发的一套WEB应用系统,使其能够适应IE11。
在升级过程中,较为深入的了解了IE11与较早版本的一些区别,以及需要修改那些地方才能适应IE11。
现整理出来一部分,供需要的同行参考。
IE11已经不再是IE了
这也是微软首次真正移除了Internet Explorer的一些特性,转而对Web标准的支持更好。
特别是更改了user-agent 字符串,这使得很多判断浏览器是否IE的代码无法工作,包括有些 JavaScript 的 isIE() 的方法在Internet Explorer 11上执行会返回 false。
在IE11中,user-agent 比之前的版本要短很多,而且去掉了最关键的MSIE的关键字(这在IE10中还有):
Internet Explorer 11 的 user-agent:
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko
鉴于此,之前多数使用 MSIE 来判断是否IE浏览器的代码都无法工作。
此外微软还更改了navigator 对象:navigator.appName 值为“Netscape”,而navigator.product 值为“Gecko”,据说这样修改为了满足HTML5而进行的,是 HTML5 中实际指定的。
在 HTML5 中要求这两个属性必须返回上述对应的值,显然IE 11遵守了这个规定。
此举导致一些根据navigator 对象判断浏览器型号的JavaScript 代码会将IE11识别成基于Gecko的浏览器。
下面的代码可以用来判断不同的浏览器以及他们的版本:
//浏览器版本信息
window.GLOBAL = {
BROWSER : (function() {
var u = erAgent.toLocaleLowerCase(),
msie = /(msie) ([\d.]+)/,
chrome = /(chrome)\/([\d.]+)/,
firefox = /(firefox)\/([\d.]+)/,
safari = /(safari)\/([\d.]+)/,
opera = /(opera)\/([\d.]+)/,
ie11 = /(trident)\/([\d.]+)/,
//match方法返回的是数组,0个元素是匹配的完整表达式,1和2个是匹配的子表达式b=u.match(msie)||u.match(chrome)||u.match(firefox)||u.match(safari)||u.match( opera)||u.match(ie11);
return {NAME: b[1], VERSION: parseInt(b[2])};
})()
}
获取的的时候使用:
;
window.GLOBAL.BROWSER.VERSION);
//注意,IE11的版本是trident,版本是7;
如果仅仅是想判断是不是IE(包括早期版本),另一种办法是判断能不能实例化ActiveXObject:
Var IsIE= !!window.ActiveXObject || "ActiveXObject" in window document.all不被推荐
从IE4 开始,document.all 在IE中举足轻重。
比起 document.getElementById() 来说,document.all 是IE方式的获取元素的引用的方法。
尽管IE5增加对DOM的支持,但document.all 一直沿用至IE10。
在Internet Explorer 11中document.all 并没有真正被删除,但不推荐使用。
document.all这种方法有一个十分讨厌的问题,即当元素只有一个时,Document.all.elementName[0]会报出异常,需要用Document.all.elementName直接获取;而document.getElementsByName(“elementName”)[0]则不会,因此,在你不能确定有多少个元素时(有可能没有或者只有一个),显然使用document.getElementsByName更为通用。
attachEvent()方法被废弃
该方法用于添加事件处理器,对应的 detachEvent() 用来移除事件处理器。
这两个方法将在Internet Explorer 11中删除。
移除这两个方法需要改用如下逻辑:
其他被删除的特性还包括:
window.execScript() –IE版本的 eval()
window.doScroll() –IE用来滚动窗口的方式
script.onreadystatechange –IE方式的脚本加载完成的事件通知
script.readyState –IE方式的测试脚本是否加载完成的状态
document.selection –IE方式获取当前选择的文本,改document.getSelection() document.createStyleSheet –IE方式创建样式单
style.styleSheet –IE方式引用样式
所有这些被废弃的方法都有基于标准的替代方法。
HTML书写严格规范
早期的浏览器版本,能够容忍一些HTML代码的不规范。
如style=”display:none”,不能写成style=”display:‘none’”。
这种写法在IE较早版本没有问题,IE11不行了。
innerText不被推荐使用
以前,我们经常使用innerText来获取元素所包含的文本内容,如获取单元格内容用document.get ElementById(“td”).innerText,IE11中已经不被推荐使用了。
innerText 其本身就是微软自己发明的东东,改邪归正总是好的,取代的办法是改用innerHTML。
但需要注意的是,如果含有子标签,innerHTML会将子标签一块输出的。
如:
<td id=”mytd”><span>1234</span></td>
Document.getElememtById(“mytd”).innerHTML的输出值为:
<span>1234</span>
元素的id和name同时存在
如果元素只有id,没有name, document.getElementsByName()会为空,引发异常。
在ie10以前版本,document.getElementsByName()取不到name,就会去取id,只要id存在就可以。
IE11显然要求更加规范。
firstChild和nextSibling
在标准的javascrip中,空格(缩进的空格)也被算作节点,因此经常性会有空节点,
如:
<table id=”tb”>
<tr>
<td>1234</td>
<td>5678</td>
</tr>
</table>
这时使用document.get ElementById(“tb”).firstChild.firstChild.innerHTML时,会报对象为空异常,这在IE以前版本是可以取到值1234的。
解决办法:
1、使用document.getElementById(“tb”).firstChild.nodeType进行判断,为3时
是空格
2、document.get ElementsById(“tb”). getElementsByTagName("td")[0].
innerHTML来代替
3、同样道理,nextSibling用来获取同级节点的下一个节点,以前可以用
document.get ElementById(“tb”).firstChild. nextSibling.innerHTML来获取
5678,现在需要用循环或数组来获取下一个节点的内容:
document.get ElementsById(“tb”).
getElementsByTagName("td")[1].innerHTML
4、使用Jquery没有这个问题,会自动去掉空格节点
不再支持Expression
IE5及其以后版本支持在CSS中使用expression,用来把CSS属性和Javascript表达式关联起来,这里的CSS属性可以是元素固有的属性,也可以是自定义属性。
就是说CSS 属性后面可以是一段Javascript表达式,CSS属性的值等于Javascript表达式计算的结果,这看起来是一件十分美妙的事情,可以帮助我们处理很多事情,但CSS Expression的问题就在于它的计算频率要比想象的多出很多。
不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次,对浏览器性能还是有压力的。
现在,这样的事在ie11终结了。
在ie11中不能使用了,需要将JS代码或函数移到外边来。
onscroll滚动条事件
IE早期版本中,把onscroll放在body中是可以执行的,例如:
<body onscroll=” myFunction()”>
现在IE11中不行了。
需要单独注册监听,例如写成:
window.onscroll = function(){
myFunction();
}
Form中<button>按钮
<button onClick=”myFunction()”>这是按钮</button>
上面这样的按钮如果在form之外,没有什么问题,但如果在form中,在IE较早版本没发现什么,点击仅仅执行myFunction()函数,但是在IE11中,问题严重了,点击此按钮,不但执行myFunction()函数,而且立马提交form表单。
如果你设定了提交严查,这样的提交根本不会被检查而直接提交,你敢说问题不严重?解决的办法是使用<input type=”button” value=”这是按钮” onClick=” myFunction()”>来代替。
另外,在早前版本中,下面的用法是可以正常显示的
<button value=”这是按钮”></button>
IE11不能这样写了,要写成下面这样才能正常显示:
<button value=””>这是按钮</button>
window.ActiveXObject
在IE早期版本中,window.ActiveXObject返回是true,IE11中不是这样了,返回的是一串这样的字符:function ActiveXObject(){[nativ code]},显然,仅以此来判断是不是IE肯定不行了,考虑到对早期IE版本的兼容性,在创建ajax实例对象时,建议使用下面的方法来判断:
if(!!window.ActiveXObject || "ActiveXObject" in window){
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}else{
http_request = new XMLHttpRequest();
}
框架页JS函数的执行问题
在框架页上,如果有自动执行的JS函数,要放在页面的上面部分,不能放在最后面,否则不能自行启动。
这种情况在IE早期版本中并无问题,在IE11中却不行。
参见下图:
写在这里才行
自启动函数写在这
里不能自动运行
window.navigate不被推荐
window.navigate(url)在IE11中将不再推荐使用但仍然可以用,建议改用标准window.location.href =url来实现页面跳转或者刷新。
关于scroll处理滚动条
控制页面是否出现滚动条,可以使用<body scroll=”no/auto”>,但这个属性方法我并未在W3C标准中找到,但在IE11中确实是可用的。
尽管如此,我还是建议使用更为通用的办法:
<body style="overflow:scroll;overflow-y:hidden">//去掉竖滚动条
<body style="overflow:scroll;overflow-x:hidden">//去掉横滚动条
<body style="overflow:hidden">//全部去掉
或者使用css:body{ overflow:auto; overflow-x:hidden}
关于获取CSS内部属性
之前的IE版本只能使用下面方法获取元素内部css的属性值:
var computedStyle = obj.currentStyle;
alert(computedStyle.paddingLeft);
现在,IE11已经支持标准的js方法,同时也保留了原来的方法
var computedStyle = document.defaultView.getComputedStyle(obj, null);
alert(computedStyle.paddingLeft);
如果考虑到对以前版本的支持,可以同时使用这两种方法。
关于获取元素宽度长度计算的问题
在IE10之前的版本中,使用document.get ElementById(“name”).style.width等方法获得的数据为数值型,因此可以相加减;IE11则采用标准做法,返回的是数字+px,是个字符串,不能直接做加减法了,需要使用replace将“px”去掉后再进行数学计算。
关于select 中size与height
在早期IE版本中,select多行列表时,size可以与height同时存在,但会以size 为主,也就是说,浏览器会取这两个值中较大的一个(size会被换算为高度px值)。
IE11中情况发生变化了,height会被优先采用,而不会考虑size,因此这两个值设置时要注意,有size时,不要再设置height了。
不再支持VBScript
从IE11开始已经不再支持VBScript作为前端脚本了,所以很遗憾,要么把IE降级,要么改用javascript。
关于使用CSS实现渐变
在IE11以前,ie有自己的渐变滤镜,即
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#79bbff',endCo lorstr='#378de5',GradientType=0)
在IE11已经不支持这个滤镜了,改为使用:
background:-ms-linear-gradient(top, #79bbff 5%, #378de5 100%);
一般情况下,为了适应各类型浏览器,建议使用以下CSS
.linear{
background:-webkit-gradient(linear, left top, left bottom, color-start(0.05, #79bbff), color-stop(1, #378de5));
background:-moz-linear-gradient(top, #79bbff 5%, #378de5 100%);
background:-o-linear-gradient(top, #79bbff 5%, #378de5 100%);
background:-ms-linear-gradient(top, #79bbff 5%, #378de5 100%);
background:linear-gradient(to bottom, #79bbff 5%, #378de5 100%);
background:-webkit-linear-gradient(top, #79bbff 5%, #378de5 100%);
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#79bbff',e ndColorstr='#378de5',GradientType=0);
}
IE11不再支持条件性注释
IE11不再支持条件性注释,下面代码不会被执行
<!--[if IE6]>
<style type="text/css">
/* styles for IE6 goes here */
</style>
<![endif]-->
showModalDialog打开框架页窗口太小
IE11中,使用showModalDialog(也包括showModalLessDialog)时,窗口很小(有框架的页),并且设置dialogHeight:和dialogWidth均不管用,不知道为什么,我的处理办法是要么改成window.open()来代替,要么在框架页中加上
<meta http-equiv="x-ua-compatible" content="IE=7">
这实际上是告诉浏览器,回退到ie7去处理该页面,这显然并不理想。
网上有种说法:“这其实是标准的问题,ie11更加标准化,frameset走的是 XHTML 1.0 Frameset,如果用其它协议可能出现此类问题,把Frameset 页面的DOCTYPE改为frameset 协议或者直接把DOCTYPE 这一行删除即可。
”
对此,我试了试,没好使。
想必showModalDialog毕竟是IE独有的东西,一直没纳入W3C 标准,或许未来某一天就被废弃了。
看来,还是少用为妙。
突然想到可不可以在被打开的页面中,使用下面代码控制或者resize()以下,我不想用了,所以没有试过行不行,感兴趣的朋友可以试一下:
<script>
window.dialogHeight=document.body.scrollHeight+"px";
window.dialogWidth=document.body.scrollWidth+"px";
</script>
html5删除了frame 和frameset
这个本来和IE11没啥关系,但既然碰到了这个问题,同时也怀疑前面的那个问题可能与此有关,也写在这里吧。
html5删除了frame 和 frameset等元素,添加了article、detailist、figure、footer、header、nav、section、source等新元素。
但iframe被保留了,至于保留到什么时候,没人知道。
有人建议使用div+css(主要是div的float属性来布局)或者iframe来代替frameset。
但iframe仅被有限支持,只有一个属性src,其他属性不行了。
动态部分可以使用Ajax实现,因此已经没有必要使用框架了
也有人建议使用jquery的方法来动态加载:
$("#divID").load("xx.htm")页面就可以了。
个人觉得,frame以及frameset还是很好用的,布局方便,局部更新方便,确实应该保留才对。
关于checkbox的选中问题
在IE以前版本中,document.get ElementById(“checkbox_id”).checked就可以表示被选中,IE10以后版本不行,需要明确:
document.get ElementById(“checkbox_id”).checked=true
<fieldset><legend>属性
IE11以前版本,<legend>文本默认是在左侧的,现在则默认居中,要使其局左,须明确写明
<legend align="left">季度计划属性信息修改</legend>。
禁止退格键返回上一页
禁止退格键返回上一页的功能(当input为readonly时),原来的写法在IE11中不灵了,参考网上的资料,重写了下面方法:
document.onkeydown = function(e){//适合ie和chrome,其他的用onkeypress var keyEvent;
if(e.keyCode==8){
var d=e.srcElement||e.target;
if(d.tagName.toUpperCase()=='INPUT'||d.tagName.toUpperCase()=='TEXTAREA'){
keyEvent=d.readOnly||d.disabled;
}else{
keyEvent=true;
}
}else{
keyEvent=false;
}
if(keyEvent){
e.preventDefault();
}
}
JS中getYear()与getFullYear()
这两个方法在IE11早期版本中都会返回当前本地年份,如2016,但在IE11中不行了,显然IE11遵循了js标准,要想获得yyyy格式的年份,必须使用getFullYear(),而getYear()返回的是1900年以来的年代差,相差1900年,可以简单理解为getFullYear()=getYear()+1900。