浏览器兼容性问题总结

一、浏览器内核介绍

1、定义

浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引擎”,不过我们一般习惯将之称为“浏览器内核”。负责对网页语法的解释(如标准通用标记语言下的一个应用HTML、JavaScript)并渲染网页。 所以,通常所谓的浏览器内核也就是浏览器所采用的渲染引擎,渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。不同的浏览器内核对网页编写语法的解释也有不同,因此同一网页在不同的内核的浏览器里的渲染效果也可能不同,这也是网页编写者需要在不同内核的浏览器中测试网页显示效果的原因。

2、常见的浏览器内核

IE浏览器:Trident内核,也是俗称的IE内核;

Firefox浏览器:Gecko内核,俗称Firefox内核;

Safari浏览器:Webkit内核;

Opera浏览器:最初是自己的Presto内核,后来是Webkit,现在是Blink内核

Chrome浏览器:以前是Webkit内核,现在是Blink内核;

360浏览器、猎豹浏览器:IE+Chrome双内核;

搜狗、遨游、QQ浏览器:Trident(兼容模式)+Webkit(高速模式);

百度浏览器、世界之窗:IE内核;

2345浏览器:以前是IE内核,现在也是IE+Chrome双内核

二、HTML兼容

1、IE不支持html5标签

问题说明:使用html5标签能让代码语义化更直观,而且更方便SEO优化。但是此html5新标签在IE6/IE7/IE8上并不能识别,需要进行JavaScript处理

解决方案:借用前辈封装好的js库— html5shiv.js

// 增加判断,如果是IE9以下的IE浏览器将创建script标签引入html5shiv,这样非IE浏览器就会忽视这段代码,也就不会进行无谓的http请求了

// Google的html5shiv包
<!--[if lt IE9]> 
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->


// 国内的html5shiv包
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<![endif]-->

2、input标签的placeholder在iE10以下低版本浏览器不显示问题

问题说明:placeholder是h5的新属性,IE10以前的浏览器(8、9)不支持此属性

解决方案:

方案一: jQuery三方插件  jquery-placeholder

    <!--[if lte IE 9]>
     <script src="../../js/jquery/jquery.placeholder.min.js"></script>
     <script>
        $(function(){
            $('input[placeholder]').placeholder();
        });
     </script>
    <![endif]-->

 方案二:将placeholder的值作为内容写入控件,并添加控件事件来进行模拟

;(function(){
    if( !('placeholder' in document.createElement('input')) ){
        // 匹配 除type=password以外所有input、textarea
        $('input[placeholder][type!=password],textarea[placeholder]').each(function(){   
            var self = $(this),   
            text= self.attr('placeholder');
            // 如果内容为空,则写入
            if(self.val()===""){ 
                self.val(text).addClass('placeholder');
            }
 
            // 控件激活,清空placeholder
            self.focus(function(){
                if(self.val()===text){
                    self.val("").removeClass('placeholder');
                }
            // 控件失去焦点,清空placeholder
            }).blur(function(){
                if(self.val()===""){
                    self.val(text).addClass('placeholder');
                }
            });            
        });   
    }
})();

方案三: 利用一个type为text的input作为显示,得到焦点后隐藏

            //添加显示input样式
			if( !('placeholder' in document.createElement('input')) ){
			        // 匹配 除type=password以外所有input、textarea
			        $('input[placeholder][type!=password]').each(function(){   
			        	var self = $(this);
			            var text = self.attr('placeholder');
			            self.val(text).css({
	                        "color": "#a6a6a6"
	                    });
			        });   
			}
			
			//创建password的placeholder效果
			function createPlaceholder(selector){
				 $("#"+selector+"Tips").focus(function() {
	            	$(this).hide().siblings("#"+selector).show().focus();
	            });
	            $("#"+selector).blur(function() {
	                if ($(this).val() == '') {
	                    $(this).hide().siblings("#"+selector+"Tips").show();
	                }
	            })
			}
			
	        createPlaceholder("oldPassWord");
	        createPlaceholder("newPassWord");
	        createPlaceholder("confirmPassWord");

3、IE10版本以上浏览器input标签后面自带一个X问题

问题说明: IE10,IE11浏览器当点击input text文本框时,输入文本后出现一个删除功能的X按钮
解决方案:给input添加如下CSS样式

input::-ms-clear{display:none;}

4、IE8不支持canvas标签

问题说明:canvas在ie8以及低版本中都不被支持
解决方案:可以下载Google出的Excanvas.js库,它是利用IE支持的VML对象来模拟Canvas的绘图的,有些情况下可用,但无法穷尽Canvas的所有功能,在页面中引用Excanvas.js文件,最好在<head>标签中

三、CSS兼容

 1、 css hack

由于不同厂商的浏览器,比如Internet Explorer, Safari, Mozilla, Firefox,Chrome等,或者是同一厂商的浏览器的不同版本,如IE6和IE7,对CSS的解析认识不完全一样,因此会导致生成的页面效果不一样,得不到我们所需要的页面效果。 这个时候我们就需要针对不同的浏览器去写不同的CSS,让它能够同时兼容不同的浏览器,能在不同的浏览器中也能得到我们想要的页面效果。简单的说,CSS hack的目的就是使你的CSS代码兼容不同的浏览器。

【1】css hack方式 ——条件注释法

    <!--[if IE]>
    这段文字只在IE浏览器显示
    <![endif]-->


    <!--[if IE 6]>
    这段文字只在IE6浏览器显示
    <![endif]-->
    
    
    <!--[if gte IE 6]>
    这段文字只在IE6以上(包括)版本IE浏览器显示
    <![endif]-->
    
    
    <!--[if ! IE 8]>
    这段文字在非IE8浏览器显示
    <![endif]-->
    
    
    <!--[if !IE]>
    这段文字只在非IE浏览器显示
    <![endif]-->

【2】css hack方式 ——类内属性前缀法

属性前缀法是在CSS样式属性名前加上一些只有特定浏览器才能识别的hack前缀,以达到预期的页面展现效果。

hack写法IE6(S)

IE6

(Q)

IE7

(S)

IE7

(Q)

IE8

(S)

IE8

(Q)

IE9(S)

IE9

(Q)

IE10

(S)

IE10

(Q)

**colorYYYYNYNYNY
++colorYYYYNYNYNY
--colorYYNNNNNNNN
__colorYYNYNYNYNN
##colorYYYYNYNYNY
\0color: red\0NNNNYNYNYN
\9\0color: red\9\0NNNNNNYNYN
!importantcolor: blue !important;NNYNYNYNYY

【3】css hack方式 ——选择器前缀法

选择器前缀法是针对一些页面表现不一致或者需要特殊对待的浏览器,在css选择器前上一些只有某些特定浏览器才能识别的前缀进行hack。

    *html *前缀只对IE6生效
    *+html *+前缀只对IE7生效
    @media screen\9{...} 只对IE6/7生效
    @media \0screen {body { background: red; }} 只对IE8有效
    @media \0screen\,screen\9{body { background: blue; }} 只对IE6/7/8有效
    @media screen\0 {body { background: green; }} 只对IE8/9/10有效
    @media screen and (min-width:0\0) {body { background: gray; }} 只对IE9/10有效
    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {body { background: orange; }} 只对IE10有效等等

2、IE不支持css3新属性

问题说明:css3.0增加的新属性,如投影、渐变、旋转、圆角等等~ 这些新标准属性在ie6、ie7、ie8浏览器版本里得不到很好的支持

解决方案:在属性前加浏览器前缀兼容早期浏览器

-moz- :火狐浏览器 
-webkit- : Safari, 谷歌浏览器等使用Webkit引擎的浏览器  
-o- Opera:浏览器(早期) 
-ms- :IE

// 实例
-webkit-box-shadow: #666 0px 2px 3px;
-moz-box-shadow: #666 0px 2px 3px;
-ms-box-shadow: #666 0px 2px 3px;
-o-box-shadow: #666 0px 2px 3px;
box-shadow: #666 0px 2px 3px;

3、 不同浏览器的标签默认的margin和padding不同

解决方案:css 里增加通配符样式

* {
    margin: 0;
    padding: 0;
}

 4、 文字大小不一致

问题说明:字体大小在不同浏览上不一致,例如font-size:14px,在 IE 中的实际行高是16px,下面有3px留白;在 Firefox 中的实际行高是17px,下面有3px留白,上边1px留白;在 opera 中就更不一样了

解决方案:css 里增加通配符样式

    html {
      font-size: 14px;
      line-height: 14px;
    }

5、IE6边距问题

问题说明:块元素标签 设置float 后,又设置了 margin 的情况下,在IE6中显示 margin 比设置的值大,常见症状是IE6中后面的一块被顶到下一行

解决方案:在 float 的标签样式中加入 display:inline;  将其转化为行内属性备

6、当标签的高度设置小于10px,在IE6、IE7中会超出自己设置的高度

解决方案:超出高度的标签设置overflow:hidden,或者设置line-height的值小于你的设置高度

    

7、图片默认有间距

问题说明:几个 img 标签放在一起的时候,有些浏览器会有默认的间距

解决方案:使用 float 属性为 img 布局(所有图片左浮)


8、IE9以下浏览器不能使用opacity

    .box {
      /* 一点其他的样式... */
      background-color: #000;
      opacity: 0.5;
 
      /* 兼容Firefox浏览器 */
      -moz-opacity: 0.5;
      filter: alpha(opacity=50);
      
      /* IE6 */
      filter: progid:DXImageTransform.Microsoft.Alpha(style=0, opacity=50);
    }

9、边距重叠问题;

问题说明:当相邻两个元素都设置了margin 边距时,margin 将取最大值,舍弃最小值;

解决方案:为了不让边距重叠,可以给子元素增加一个父级元素,并设置父级元素为overflow:hidden;

10、最低高度 min-height 不兼容

问题说明:因为 min-height 本身就是一个不兼容的 CSS 属性,所以设置 min-height 时不能很好的被各个浏览器兼容

解决方案:如果我们要设置一个标签的最小高度 200px ,设置如下

{ 
  min-height: 200px; 
  height: auto !important; 
  height: 200px; 
  overflow:visible;
 }

 

11、text-align居中问题

问题说明: 首先在父级元素定义 text-align: center; 这个的意思就是在父级元素内的内容居中;对于IE这样设定就已经可以了。但在mozilla中不能居中。

解决方案:在子元素定义时候设定时再加上 margin-right: auto; margin-left: auto; 

12、cursor:hand 显示手型在safari 上不支持

解决方案:统一使用 cursor:pointer

13、IE8以下不支持CSS3的background-size属性

解决方案:使用滤镜filter

14、IE浏览器div最小宽度和最小高度不生效的问题

问题说明:IE不认得min-这个定义,但实际上它把正常的width和height当作有min的情况来使。这样问题就大了,如果只用宽度和高度,正常的浏览器里这两个值就不会变,如果只用min-width和min-height的话,IE下面根本等于没有设置宽度和高度。比如要设置背景图片,这个最小宽度是比较重要的。

解决方案:要解决这个问题,可以这样设置

        #box {
            width: 80px;
            height: 35px;
        }

        html>body #body {
            width: auto;
            height: auto;
            min-width: 80px;
            min-height: 35px;
        }


15、 超链接访问过后hover样式就不出现的问题

问题说明:被点击访问过的超链接样式不再具有hover和active样式了,很多人应该都遇到过这个问题

解决方案:是改变CSS属性的排列顺序: L-V-H-A

a:link {}
a:visited {}
a:hover {}
a:active {}

16、对盒模型的解析不一致

问题说明:

        .box {
            width: 100px; 
            border: 1px;
        }
        /* IE浏览器解析:box元素宽为100px */
        /* w3c标准浏览器解析: box元素宽为100 + 1*2 = 102px; */

解决方案:div { margin: 30px !important; margin: 28px; } 注意这两个 margin 的顺序一定不能写反, IE不能识别 !important 这个属性,但别的浏览器可以识别。所以在IE下其实解释成这样:div{ maring: 30px; margin: 28px; } 重复定义的话按照最后一个来执行

17、IE8不支持CSS媒体查询

问题说明:IE8不支持CSS媒体查询,对响应式设计大大不利。Respond.js可帮助IE6-8兼容 "min/max-width" 媒体查询条件

解决方案:在页面中所有css文件的引用位置之后引用Respond.js。而且Respond.js的引用得越早,用户看到页面闪烁的机会越小

<script src="https://cdn.bootcss.com/respond.js/1.1.0/respond.min.js"></script>

三、js兼容

1、事件绑定

其他浏览器:

dom.addEventListener('click',function(event){},false);

IE7、IE8:

dom.attachEvent();

解决方案:

        function addEvent(ele, evType, fn, useCapture) {
            if (ele.addEventListener) { // W3C标准
                ele.addEventListener(evType, fn, useCapture);
                return true;
            } else if (ele.attachEvent) { // IE
                var r = ele.attachEvent('on' + evType, fn); // IE5+
                return r;
            } else {
                ele['on' + evType] = fn; // DOM事件
            }
        }

2、获取event事件对象

var ev = ev || window.event

3、获取event事件源对象

var srcObj = event.srcElement?event.srcElement:event.target

4、阻止事件冒泡传播

    // js阻止事件传播,这里使用click事件为例
    document.onclick = function (e) {
      var e = e || Window.event;
      if (e.stopPropagation) {
        e.stopPropagation(); // W3C标准
      } else {
        e.cancelBubble = true; // IE... .
      }
    }

5、阻止事件默认行为

    // js阻止默认事件,一般阻止a链接href, form表单submit提交
    document.onclick = function (e) {
      var e = e || Window.event;
      if (e.preventDefault) {
        e.preventDefault(); // W3C标准
      } else {
        e.returnValue = false; // IE... .
      }
    }

6、滚轮事件兼容问题

document.onclick = function (e) {
    e = e || window.event;
    var bool = true;
    if (e.wheelDelta) {
        bool = e.wheelDelta > 0 ? true : false; //谷歌和ie
    } else {
        bool = e.detail < 0 ? true : false; //火狐
    }
}

7、ajax兼容问题

    var oAjax = null;
    if (window.XMLHttpRequest) {
      oAjax = new XMLHttpRequest();
    } else {
      //只支持E6浏览器
      oAjax = new ActiveXObject("Microsoft.XMLHTTP");
    }

8、 HTML对象获取问题

其他浏览器:

document.getElementById("idName");

IE浏览器:

document.idname
document.getElementById("idName");

解决方案:

document.getElementById("idName");



9、 const定义常量问题

其他浏览器:可以使用const关键字或var关键字来定义常量

const AGE = 18;
var AGE = 18;

IE浏览器:只能使用var关键字来定义常量

var AGE = 18;

解决方案:统一使用var关键字来定义常量

var AGE = 18;

 

10、 window.location.href 问题

Firefox1.5.x下:只能使用window.location

window.location

其他浏览器:可以使用window.location 或 window.location.href

window.location
window.location.href

解决方案:统一使用 window.location 来代替 window.location.href

window.location

 11、 访问frame对象

其他浏览器:使用 window.frameName 来访问 frame 对象

window.frameName

IE浏览器:使用 window.frameId 或者 window.frameName 来访问 frame 对象

window.frameId 
window.frameName

解决方案:统一使用window.document.getElementById("frameId") 来访问 frame 对象

window.document.getElementById("frameId") 

 

12、 访问父节点

其他浏览器:使用obj.parentNode 访问 obj 的父结点

obj.parentNode 

IE浏览器:使用 obj.parentElement 或 obj.parentNode  访问 obj 的父结点

obj.parentElement 
obj.parentNode 

解决方案:统一使用obj.parentNode 来访问 obj 的父结点

obj.parentNode 

 

13、innerText 的问题

问题说明:innerText 在IE中能正常工作,但是 innerText 在FireFox中却不行

解决方案:在非IE浏览器中使用 textContent 代替 innerText

if (navigator.appName.indexOf("Explorer") > -1) {
    document.getElementById("element").innerText = "text"; // IE
} else {
    document.getElementById("element").textContent = "text"; // 其他
}

14、建立单选按钮

// IE以外的浏览器
var radioBtn = document.createElement("input");
radioBtn.setAttribute("type", "radio"); 
radioBtn.setAttribute("name", "radiobtn"); 
radioBtn.setAttribute("value", "checked");
// IE
var radioBtn = document.createElement("<input name="radioBtn" type="radio" value="checked" />");

15、用 setAttribute 设置事件

问题说明:btn.setAttribute("onclick", "") 这条语句利用setAttribute设置onclick属性增加事件,简单很好理解。但是IE不支持。

解决方案:为达到兼容各种浏览器的效果,可以用点符号来设置Element的对象属性、集合属性和事件属性

document.getElementById("foo").className = "fruit";
document.getElementById("foo").style.cssText = "color: #00f;";
document.getElementById("foo").style.color = "#00f";
document.getElementById("foo").onclick = function () {
    alert("This is a test!");
}

16、用 setAttribute 设置class

问题说明:使用setAttribute("class", className)语句动态设置Element的class属性在其他浏览器是行的通的,在IE中却不行。因为使用IE内核的浏览器不认识"class",要改用"className";同样,firefox 也不认识"className"

解决方案:常用的方法是二者兼备

element.setAttribute("class", className); // 其他
element.setAttribute("className", className);  // IE

17、IE8数组不支持forEach方法问题

问题说明:forEach 是在第五版本里被添加到 ECMA-262 标准的,对于IE8及以下版本的IE浏览器来说,都不支持forEach()

解决方案:在调用 forEach 之前插入下面的代码,在不支持的情况下使用 forEach()。该算法是ECMA-262 第5版中指定的算法。算法假定Object和TypeError拥有它们的初始值。callback.call 等价于Function.prototype.call()

if (!Array.prototype.forEach) {
    Array.prototype.forEach = function forEach(callback, thisArg) {
        var T, k;
        if (this == null) {
            throw new TypeError("this is null or not defined");
        }
        var O = Object(this);
        var len = O.length >>> 0;
        if (typeof callback !== "function") {
            throw new TypeError(callback + " is not a function");
        }
        if (arguments.length > 1) {
            T = thisArg;
        }
        k = 0;
        while (k < len) {
            var kValue;
            if (k in O) {

                kValue = O[k];
                callback.call(T, kValue, k, O);
            }
            k++;
        }
    };
}

 

18、IE8对象不支持bind方法问题

问题说明:现在大部分主流浏览器都支持bind,很不幸,IE8却不支持

解决方案:如果碰到了bind的兼容问题,那么只能自己写拓展了,就是增加 property 原型使得所有浏览器都能支持 bind 方法

if (!Function.prototype.bind) {
    Function.prototype.bind = function (oThis) {
        if (typeof this !== "function") {
            throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
        }
        var aArgs = Array.prototype.slice.call(arguments, 1),
            fToBind = this,
            fNOP = function () {},
            fBound = function () {
                return fToBind.apply(this instanceof fNOP && oThis ?
                    this :
                    oThis,
                    aArgs.concat(Array.prototype.slice.call(arguments)));
            };
        fNOP.prototype = this.prototype;
        fBound.prototype = new fNOP();
        return fBound;
    };
}

 

19、对象不支持trim属性或方法

问题说明:ie8及以下 String 没有trim 方法

解决方案:

if ( !String.prototype.trim ) {
  String.prototype.trim = function () {
    return this.replace(/(^\s*)|(\s*$)/g, "");
  }
}

20、获取元素的非行间样式值

    //获取元素属性值的兼容写去
    function getStyle(obj, attr) {
      if (obj.currentStyle) {
        return obj.currentstyle[attr];
      } else {
        //IE
        return window.getComputedStyle(obj, null)[attr];
      }
    }

四、兼容IE8、IE9的一些建议

1、强制ie以最新的版本模式对页面进行渲染,X-UA-Compatible是IE8的一个专有属性,它告诉IE8采用何种IE版本去渲染网页,在html的标签中使用。Edge模式告诉IE以最高级模式渲染文档,也就是任何IE版本都以当前版本所支持的最高级标准模式渲染,避免版本升级造成的影响。简单的说,就是什么版本IE就用什么版本的标准模式渲染。chrome=1 是谷歌自己做的一个插件:Google Chrome Frame(谷歌内嵌浏览器框架GCF)。这个插件可以让用户的浏览器外观依然是IE的菜单和界面,但用户在浏览网页时,实际上使用的是Google Chrome浏览器内核,而且支持IE6、7、8等多个版本的IE浏览器,要使用chrome=1,要安装GCF,并且指定页面使用chrome内核来渲染。

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

2、css样式,尽量少用css3的这些伪类选择器,如果使用了,在后期做兼容会很累,如果项目硬要兼容IE8+,那就请你从一开始就避免这些伪类的使用吧。避免了最难解决的伪类问题后,剩下的就是针对IE8 IE9做一些样式上的微调,将会异常轻松。

3、IE8是不支持className选择节点的,所以,最省时省力的方法,我们在选择节点时,可以多使用jQuery选择器,说实话,jQuery的兼容性还真的好。当然如果你的父节点不是element,没法用jq的时候,只能自己拓展了

4、如果你不小心用到了某个jq版本的text()方法,那么你要注意,有可能IE8不兼容,最好使用innerHTML

5、使用jQuery的Deferred对象执行异步操作,在JQuery 1.5之前,Ajax仅支持一个回调函数,但在JQuery的1.5版本中,引入了 Deferred对象,它和ES6的Promise对象长的有点像,jQuery的Deferred对象也有resolve、reject、then方法,还有done、fail、always......方法。jQuery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。它允许注册多个回调函数,并且能传递任何同步或异步函数的执行状态:成功或失败。简单说, Deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。

6、UI库选择,在开发项目的时候我建议的是尽量使用别人做好兼容的框架,ui方面如果你的项目jq为主强烈建议layui(兼容ie8的ui库),easyui(一款严重被低估了的ui库,目前已经支持jq、vue、angula、react,并且性能很好,尤其在使用表格大数据渲染方面相当出色,采用虚拟滚动视图,渲染海量数据)

7、上传,ie9及Ie9以下目前的上传问题,ie9及以下不支持FileReader和formdata.(建议使用webupload上传插件,据说兼容ie6+),还有一些其他flash上传的插件兼容性都比较好uploadify,SWFUpload等等,使用方式类似webupload,所以为什么不选择百度的呢。

8、下载,最好是window.open,人类使用的浏览器基本无兼容问题,如果你运气不好,后端偏要你使用post方式下载,这里建议ajax配合download.js(一款开源的下载方案)

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@Demi

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值