那些为了兼容IE8遇到的坑

1,616 阅读5分钟

前言

项目开发快要结束,客户说要兼容IE8,突然头痛。用IE8打开项目,果然一片空白,控制台一片红,真是红红火火恍恍惚惚。

于是乎,准备用这篇文章记录下兼容IE8遇到的各种问题,以及解决方法。

遇到的问题

1、不支持console.log

查了半天,找到了一个比较好的方法

        var funcs = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml',
            'error', 'exception', 'group', 'groupCollapsed', 'groupEnd',
            'info', 'log', 'markTimeline', 'profile', 'profileEnd',
            'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'
        ];
        for (var i = 0, l = funcs.length; i < l; i++) {
            var func = funcs[i];
            if (!console[func])
                console[func] = function () {};
        }

2、控制台报错:SCRIPT1010: 缺少标识符

这类错误是由于一些js文件使用了js中保留的关键字,如: default, delete 等。在IE8中,default就是保留的关键字。

default比较好解决,可以使用obj['default']的写法,delete暂时没有遇到。

3、甘特图:dhtmlxgantt.js

IE8不支持这个,暂时没找到解决方法,为了让项目先跑起来,注释掉了甘特图配置部分的代码。

4、控制台报错:TypeError: 对象不支持“indexOf”属性或方法

IE8有许多不支持的方法,比如trim, indexOf等等。在网上找到了es5-shim.js,解决。

es5-shim用来模拟一些IE6/7/8浏览器不兼容的ES5语法。

以下解释出自zhidao.baidu.com/question/20…

其中还有一个es5-sham.js,作用是让ES5中其他无法被完美模拟的方法,由sham完成。sham只承诺你用的时候代码不会崩溃,至于对应的方法是不是起作用它就不保证了,它只是尽力模拟(as close as possible)。

所以如果你要用的方法在shim中都包含了,那么就不需要sham。sham能不引用就不引用。但是如果你要用的方法只包含在sham中,那你要明白sham只是保证不崩溃,并不能保证对应方法的功能正确。

5、placeholder无效

IE8没有实现placeholder,只能使用其他方法来模拟。在网上找了一些方法,虽然代码少,但是效果都不是很好。于是抱着试一试的想法,copy了一段很长的代码,然后自己改了改,意外的不错。使用的是文章中的方法2,使用js和jq来生成一个label,input中没内容时就用label覆盖在上面。

文章地址:www.cnblogs.com/meggie523/p…

6、控制台报错:对象不支持“addEventListener”属性或方法

一样也是因为IE8没有实现,引入下面的代码解决:

        //为window对象添加
        addEventListener = function (n, f) {
            if ("on" + n in this.constructor.prototype)
                this.attachEvent("on" + n, f);
            else {
                var o = this.customEvents = this.customEvents || {};
                n in o ? o[n].push(f) : (o[n] = [f]);
            };
        };

        removeEventListener = function (n, f) {
            if ("on" + n in this.constructor.prototype)
                this.detachEvent("on" + n, f);
            else {
                var s = this.customEvents && this.customEvents[n];
                if (s)
                    for (var i = 0; i < s.length; i++)
                        if (s[i] == f) return void s.splice(i, 1);
            };
        };

        dispatchEvent = function (e) {
            if ("on" + e.type in this.constructor.prototype)
                this.fireEvent("on" + e.type, e);
            else {
                var s = this.customEvents && this.customEvents[e.type];
                if (s)
                    for (var s = s.slice(0), i = 0; i < s.length; i++)
                        s[i].call(this, e);
            }
        };

        //为document对象添加
        HTMLDocument.prototype.addEventListener = addEventListener;
        HTMLDocument.prototype.removeEventListener = removeEventListener;
        HTMLDocument.prototype.dispatchEvent = dispatchEvent;
        HTMLDocument.prototype.createEvent = function () {
            var e = document.createEventObject();
            e.initMouseEvent = function (en) {
                this.type = en;
            };
            e.initEvent = function (en) {
                this.type = en;
            };
            return e;
        };

        //为全元素添加
        var tags = [
                "Unknown", "UList", "Title", "TextArea", "TableSection", "TableRow", "Table", "TableCol", "TableCell", "TableCaption", "Style", "Span",
                "Select", "Script", "Param", "Paragraph", "Option", "Object", "OList", "Meta", "Marquee", "Map", "Link", "Legend", "Label", "LI", "Input",
                "Image", "IFrame", "Html", "Heading", "Head", "HR", "FrameSet", "Frame", "Form", "Font", "FieldSet", "Embed", "Div", "DList", "Button", "Body", "Base", "BR", "Area", "Anchor"
            ],
            html5tags = [
                "abbr", "article", "aside", "audio", "canvas", "datalist", "details", "dialog", "eventsource", "figure", "footer", "header", "hgroup", "mark", "menu", "meter", "nav", "output", "progress", "section", "time", "video"
            ],
            properties = {
                addEventListener: {
                    value: addEventListener
                },
                removeEventListener: {
                    value: removeEventListener
                },
                dispatchEvent: {
                    value: dispatchEvent
                }
            };

        for (var o, n, i = 0; o = window["HTML" + tags[i] + "Element"]; i++)
            tags[i] = o.prototype;
        for (i = 0; i < html5tags.length; i++)
            tags.push(document.createElement(html5tags[i]).constructor.prototype);
        for (i = 0; o = tags[i]; i++)
            for (n in properties) Object.defineProperty(o, n, properties[n]);

7、对象不支持“atob”属性或方法、对象不支持“btoa”属性或方法

IE8没有实现,查了半天找到了一个使用原生js实现base64编码解码的js:Base64.js

8、CSS border-radius失效

IE8不支持,需要根据样式使用PIE.htc文件,下载地址:css3pie.com/

使用方法,在CSS中加入以下代码:

    -ms-behavior:url(css/PIE.htc);
    behavior: url(css/PIE.htc);

一些注意点:

1、behavior的url是相对于html页面的地址;

2、有时使用以后会出现无法显示的情况,此时可以给元素加上position:relative;

3、服务器不支持,需要文件类型的支持 AddType text/x-component .htc;

4、CSS不支持单独设置,只能使用缩写。

参考文章:blog.csdn.net/duoduo_qiu/…

9、CSS box-shadow失效

看百度说PIE.htc一样可以解决这个问题,但是反复尝试以后没有成功,暂未解决。

10、CSS linear-gradient渐变色失效

PIE.htc貌似一样可以解决,但是之前使用了另一种方法成功了,就没有尝试,在CSS中加入以下代码:

filter:progid:DXImageTransform.Microsoft.Gradient(enabled=bEnabled,startColorStr=iWidth,endColorStr=iWidth,GradientType=0 | 1) 

属性:

enabled:可选项。布尔值(Boolean)。设置或检索滤镜是否激活。 可选值为true或false。

true: 表示滤镜激活。 false表示滤镜被禁止。

第二个参数和第三个参数都是可选的,且取值范围都是#FF000000 - #FFFFFFFF。

第二个参数:startColorStr 字符串。设置或检索色彩渐变的开始颜色和透明度。

第三个参数:endColorStr 字符串。 设置或检索色彩渐变的结束颜色和透明度。

第四个参数:GradientType 默认值是1,表示水平渐变。0表示垂直渐变。

参考文章:www.cnblogs.com/wyf-gis/p/4…

11、CSS calc()失效

IE8不支持动态属性,使用了jq来设置样式:

$('.box').css('height', '100%').css('height', '-=60px');

等同于height: calc(100% - 60px)

12、bootstrap布局失效

针对 IE8 需要额外引入 Respond.js 文件以支持媒体查询(media query)。下载地址:www.bootcdn.cn/respond.js/…

参考文章:www.cnblogs.com/mengfangui/…

13、pqGrid表格不显示,控制台报错:无法获取未定义或 null 引用的属性“colModel”

一开始以为是IE8不支持项目中使用的初始化方式造成的,于是花了一天左右把表格初始化的代码给修改以后可以运行了,以为确实是这个原因。然后修改第二个表格的时候又报了这个错,又从头开始找原因,一番折腾以后发现是colModel中数组的最后一个元素后面有逗号,比如:

var arr1 = [1, 2, 3,];
var arr2 = [
	{
    	name: 'joe satriani',
    },
    {
    	name: 'steve vai',
    },
];

在IE8里,如果逗号后面为空,最后一个元素就会变成undefined,比如arr1就会输出[1, 2, 3, undefined],就是因为这个undefined,所以报错了。(找了半天就因为一个逗号。。)