IE8浏览器的部分兼容性问题总结

1.    兼容性问题的根本因素

浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为渲染引擎,所谓的浏览器内核也就是浏览器所采用的渲染引擎,渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。不一样的浏览器内核对网页编写语法的解释也有不一样,所以同一网页在不一样的内核的浏览器里的渲染(显示)效果也可能不一样,这也是网页编写者须要在不一样内核的浏览器中测试网页显示效果的缘由。javascript

前段时间进行了前端网页的bug修改,发现多数的bug均发生在IE8浏览器上,通过查证发现:IE8JavaScript引擎是JscriptIE9开始用Chakra,这两个版本区别很大,这就形成了IE8对于个别属性、方法的不支持或是显示效果上的差别,这里是我遇到的一些IE8上比较典型的兼容性问题及其解决办法。html

2.    indexOf

1       前端

2       java

2.1      问题

前端代码中有多处地方使用javascript数组的indexOf方法,用于查询某数组中是否存在某元素,然而测试,在IE8不支持数组元素的indexOf()方法。以下web

              var location = ['1','2','3'];ajax

              var serverData = [‘1’ , ’4’, ‘5’];chrome

              for( var i = 0; i < serverData.length; i++ )编程

              {数组

                     if( location.indexOf( serverData[i].location ) == -1 )浏览器

                            location.push( serverData[i]);

                     }

}

上述js代码的功能是将数组serverData出现的新元素添加如location中。该方法在火狐、chrome浏览器中支持,但在IE8中并不支持。

2.2      解决办法

方法一:

数组元素转化为字符串后,再使用indexOf()方法。

              var location = ['1','2','3'];

              var serverData = [‘1’ , ’4’, ‘5’];

              for( var i = 0; i < serverData.length; i++ )

              {

                     if( location.join().indexOf( serverData[i].location ) == -1 )

                            location.push( serverData[i]);

                     }

方法二(推荐方法):

添加以下js代码:

    if (!Array.prototype.indexOf)

    {

      Array.prototype.indexOf = function(elt /*, from*/)

      {

        var len = this.length >>> 0;

 

        var from = Number(arguments[1]) || 0;

        from = (from < 0)

             ? Math.ceil(from)

             : Math.floor(from);

        if (from < 0)

          from += len;

 

        for (; from < len; from++)

        {

          if (from in this &&

              this[from] === elt)

            return from;

        }

        return -1;

      };

    }

当浏览器对于数组不支持indexOf()方法时,就为数组添加该方法。

该方法会在浏览器不支持数组的indexOf方法时,为其手动添加indexOf方法,实现浏览器的兼容。

3.    ajax请求响应的异常状态码1223

3       

3.1      问题

1-    AJAX状态值与状态码区别

AJAX状态值是指,运行AJAX所经历过的几种状态,不管访问是否成功都将响应的步骤,能够理解成为AJAX运行步骤。如:正在发送,正在响应等,由AJAX对象与服务器交互时所得;使用“ajax.readyState”得到。(由数字1~4单位数字组成)

AJAX状态码是指,不管AJAX访问是否成功,由HTTP协议根据所提交的信息,服务器所返回的HTTP头信息代码,该信息使用“ajax.status”所得到。以下判断:

if(ajax.readyState == 4 && ajax.status ajax.status == 200)

最近在处理前端与服务器的交互时,发如今IE下发出的ajax请求,有时会会返回错误的状态码 1223。咱们经常使用的状态码列表中并无该状态码。

3.2      解决办法

通过查证发现,在断定一个请求是否已经完成的时候,验证xhrstatus有一点是须要注意的:有的浏览器会错误地返回204状态码,而IE(非原生的XHR对象)中会将204设置为1223Opera会在取得204时将status设置为0,而Safari 3以前的版本会将status设置为undefined

咱们经常使用的状态码:

200——请求成功

204——请求收到,但返回信息为空

即在IE浏览器下,状态码1223204是等价的,一样为请求收到,但返回信息为空,咱们只须要将ajax.status==1223的判断加入ajax.status==204的判断中便可。

4.    文件下载

4       

4.1      IE浏览器的文件下载

4.1.1          方法

       在前端的修改中,我遇到了两种下载文件的方式,一种是将服务器的文件下载到本地,另外一种是在本地将数据保存为对应格式的文件下载下来。如今推荐的是第一种方法。

              var aLink = document.createElement("a"),

              evt = document.createEvent("HTMLEvents"),

              isData = contentOrPath.slice(0, 5) === "data:",

              isPath = contentOrPath.lastIndexOf(".") > -1;

       // 初始化点击事件

       evt.initEvent("click",false,false);

       // 添加文件下载名

       aLink.download = fileName;

       // 若是是 path 或者 dataURL 直接赋值

       // 若是是 file 或者其余内容,使用 Blob 转换

       aLink.href = (isPath || isData) ? contentOrPath

                                   : URL.createObjectURL(new Blob([contentOrPath]));

       aLink.dispatchEvent(evt);

       利用a标签能够实现下载文件的效果

<a href="/images/myw3schoolimage.jpg" download="w3logo">

    经过为其添加download属性,可使其完成文件下载的功能。

4.1.2          局限

只有 Firefox Chrome 支持 download 属性。

IE下的文件下载能够经过document.execCommand()完成。

这里使用了事件模拟来触发标签a的下载事件。

4.1.3          IE浏览器的模拟事件

模拟事件大体分为模拟鼠标事件、模拟键盘事件、模拟变更事件及模拟HTML事件等。

模拟事件的过程大体分为三步:

1.  建立event对象。

经过createEvent()能够建立event对象,而传入字符串的不一样能够决定,如var event = document.createEvent(“MouseEvents”);  //建立鼠标事件对象

event = document.createEvent(“KeyboardEvent”); //建立键盘事件对象

2.  初始化事件对象

不一样类型的模拟事件对象有着不一样的初始化参数

event.initMouseEvent(“click”, true, true, document.defaultView, 0, 0, 0, 0, 0,false, false, false, false, 0, null);// 鼠标事件对象初始化

iniMouseEvent()方法接受15参数,参数以下:
  type string类型 :要触发的事件类型,例如‘click’
  bubbles Boolean类型:表示事件是否应该冒泡,针对鼠标事件模拟,该值应该被设置为true
  cancelable bool类型:表示该事件是否可以被取消,针对鼠标事件模拟,该值应该被设置为true
  view 抽象视图:事件授予的视图,这个值几乎全是document.defaultView.
  detail int类型:附加的事件信息这个初始化时通常应该默认为0
  screenX int类型 事件距离屏幕左边的X坐标
  screenY int类型 事件距离屏幕上边的y坐标
  clientX int类型 事件距离可视区域左边的X坐标
  clientY int类型 事件距离可视区域上边的y坐标
  ctrlKey Boolean类型 表明ctrol键是否被按下,默认为false
  altKey Boolean类型 表明alt键是否被按下,默认为false
  shiftKey Boolean类型 表明shif键是否被按下,默认为false
  metaKey Boolean类型: 表明meta key 是否被按下,默认是false
  button int类型: 表示被按下的鼠标键,默认是零.
  relatedTarget (object) 事件的关联对象.只有在模拟mouseover mouseout时用到。

 

 event.initKeyboardEvent(“keydown”, true, true, document.defaultView, “a”,0, “Shift”, 0); //键盘事件对象初始化。

初始化键盘事件的参数有如下几个:

type (string) - 要触发的事件类型,例如“keydown”.
  bubbles (Boolean) — 表明事件是否应该冒泡.
  cancelable (Boolean) — 表明事件是否能够被取消.
  view (AbstractView) — 被授予事件的是图. 一般值为:document.defaultView.
  key (string) — 按下的键对应的code.
  location (integer) — 按下键所在的位置. 0 :默认键盘, 1 左侧位置, 2 右侧位置, 3 数字键盘区, 4 虚拟键盘区, or 5 游戏手柄.
  modifiers (string) — 一个有空格分开的修饰符列表.
  repeat (integer) — 一行中某个键被按下的次数.

3.  触发模拟事件

经过dispatchEvent(event)来实现。

4.2      IE下的文件下载

4.2.1          方法

       IE下的文件下载能够经过document.execCommand()完成。

4.2.2          execCommand()

document.execCommand()方法处理Html数据时经常使用语法格式以下:
document.execCommand(sCommand[,交互方式, 动态参数])

中:sCommand为指令参数(以下例中的”2D-Position”),交互方式参数若是是true的话将显示对话框,若是为false的话,则不显 示对话框(下例中的”false”即表示不显示对话框),动态参数通常为一可用值或属性值(以下例中的”true”)。

document.execCommand(”2D-Position”,”false”,”true”);

调用execCommand()能够实现浏览器菜单的不少功能. 如保存文件,打开新文件,撤消、重作操做等等. 有了这个方法,就能够很容易的实现网页中的文本编辑器.

若是灵活运用,能够很好的辅助咱们完成各类项目.

使用的例子以下:

1、〖全选〗命令的实现
[格式]:document.execCommand(”selectAll”)
[说明]将选种网页中的所有内容!
[举例]在之间加入:
全选

2、〖打开〗命令的实现
[格式]:document.execCommand(”open”)
[说明]这跟VB等编程设计中的webbrowser控件中的命令有些类似,你们也可依此琢磨琢磨。
[举例]在之间加入:
打开

3、〖另存为〗命令的实现
[格式]:document.execCommand(”saveAs”)
[说明]将该网页保存到本地盘的其它目录!
[举例]在之间加入:
另存为

4、〖打印〗命令的实现
[格式]:document.execCommand(”print”)
[说明]固然,你必须装了打印机!
[举例]在之间加入:
打印

 

execCommand()还有许多其余方面的功能,详细的介绍参考:

http://blog.csdn.net/kntao/article/details/4543123

 

4.2.3          IE中的事件模拟

IE8,以及更早版本的IE,都在模仿DOM模拟事件的方式:建立事件对象,初始化事件信息,以后触发事件。固然IE在完成这几个步骤的过程是不一样的。

首先不一样于dom中建立event对象的方法,IE采用document.createEventObject()方法,而且没有参数,返回一个通用的事 件对象,接下来要对返回的event对象赋值,此时ie并无提供初始化函数,你只能采用物理方法一个一个的赋值,最后在目标元素上调用 fireEvent()方法,参数为两个:事件处理的名称和建立的事件对象。当fireEvent方法被调用的时候,event对象的 srcElementtype属性将会被自动赋值,其余将须要手动赋值。

示例以下:

var btn = document.getElementById("myBtn");
  var event = document.createEventObject();
  event.screenX = 100;
  event.screenY = 0;
  event.clientX = 0;
  event.clientY = 0;
  event.ctrlKey = false;
  event.altKey = false;
  event.shiftKey = false;
  event.button = 0;
  btn.fireEvent("onclick", event);

       这里只是简单的介绍了一些经常使用的模拟事件,详细的解释能够参考

Javascript高级程序设计》,里面有更加详细的介绍。

5.    IE下单选按钮隐藏后点击对应label没法选中的问题解决

5       

5.1      问题

项目中,有时候填写表单咱们的选项会隐藏掉radio或者checkbox,而只显示给用户对应的文字选择,若是用户点击label选择时,在FF/Chrome等标准浏览器中隐藏掉的radio/checkbox也一样随着改变选中状态,而在IE下则不会发生变化。

注意,须要指定表单元素的id属性而后使用labelfor属性绑定控件。

代码示例:
<input type="radio" name="gender" id="gender1" value="" checked="checked" />
<label for="gender1"></label>
<input type="radio" name="gender" id="gender2" value="" />
<label for="gender2"></label>
经过CSS设置display:none 或者 visibility: hidden隐藏掉radio按钮,则当点击label切换选择状态时,对应的按钮其实是未被改变状态。

5.2      解决方法

方法一:

1.经过javascript脚原本再次操做DOM保证选择状态
$("label").click(function(e){
    e.preventDefault(); 
    $("#"+$(this).attr("for")).click().change(); 
});

方法二(推荐):

不使用display:none,经过position属性定位到可视区域外,避开问题。
position: absolute;
top: -999px;

方法三:

left: -999px;经过z-index/width或透明度opacity将元素隐藏掉。
input{
    position: absolute;
    z-index: -1;
}
或者是
input{
width: 0;
}
或者是
input{
-webkit-opacity:0;
-moz-opacity:0;
opacity:0;
filter:alpha(opacity:0);

}

须要提醒的是,labelfor属性是内联元素,其对应的js属性为htmlFor,例如能够这样访问或设置for属性值。document.getElementById("xxx").htmlFor="inputid";

6.    总结

低版本IE浏览器对于对于网页内容及格式的渲染有着这样或那样的问题,然而为了实现向下的兼容,这些问题又是不可忽略的,无论怎样,可以提早了解这些差别,总会给咱们前端的实现带来一些,避免一些没必要要的问题。

相关文章
相关标签/搜索