浏览器兼容性

遇到的一些浏览器兼容问题

IE 与其他浏览器不一样的特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
IE支持currentStyle,FIrefox使用getComputStyle

IE 使用innerText,Firefox使用textContent

滤镜方面:IE:filter:alpha(opacity= num);Firefox:-moz-opacity:num

事件方面:IE:attachEvent:火狐是addEventListener

鼠标位置:IE是event.clientX;火狐是event.pageX

IE使用event.srcElement;Firefox使用event.target

IE中消除list的原点仅需margin:0即可达到最终效果;FIrefox需要设置margin:0;padding:0以及list-style:none

CSS圆角:ie7以下不支持圆角

JS

  • NodeList对象转换为数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        function convertToArray(nodes){
    var array = null;
    try{
    array = Array.prototype.splice.call(nodes,0);//IE8及更早将NodeList对象实现为一个com对象,所以会报错
    }catch(ex){
    array = new Array();
    for(var i = 0,len = nodes.length;i<len;i++){
    array.push(nodes[i]);
    }
    }
    }
  • nodeType属性,用于表示节点的类型
    例如:Node.ELEMENT_NODE(1)
    确定节点的类型:
    someNode.NodeType == Node.ELEMENT_NODE //IE没有公开Node类型的构造函数,在IE中错误
    someNode.NodeType == 1 //兼容写法

  • cloneNode()
    cloneNode方法不会复制添加到DOM节点中的JavaScript属性,例如事件处理程序等。这个方法只复制特性、(参数为true会复制子节点),但IE会复制事件处理程序
    所以,复制之前最好先移除事件处理程序

  • IE下,event对象有x,y属性,但是没有pageX,pageY属性;
    Firefox下,event对象有pageX,pageY属性,但是没有x,y属性
  • 链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序:
    L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
  • document.doctype
    • ie8及之前,会将文档类型声明解释为一个注释并当做Comment节点,document.doctype为null
    • IE9 FF:将文档类型声明作为文档第一个子节点,document.doctype为DocumentType对象
    • Safari、Chrome Opera:将其解析但不作为文档子节点
  • getElementById
    在IE7中,若有表单元素的name特性值与给定id相等,则会返回表单元素
  • setAttribute()
    IE7及以前,通过这个方法设置的class和style特性,设置事件处理程序没有任何效果
  • document.createElement()
  • 元素的子节点解析不一致
    childNodes 标准下包含了文本和元素类型的节点,非标准下,只包含元素类型的节点
  • matchesSelector()
  • 元素遍历,对于元素间的空格,IE9及之前不会返回文本节点,而其他都会返回文本节点
  • innerHTML属性返回的值
  • contentDocument
  • 页面坐标的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
    var div = document.getElementById("myDiv");
EventUtil.addHandler(div,'click',function(event){
event = EventUtil.getEvent(event);
var pageX = event.pageX,
pageY = event.pageY;
if(pageX == undefinded){
pageX = event.clientX + (document.body.scrolLeft || document.documentElement.scrolLeft;);
//IE7之前的版本:document.body
}
if(pageY == undefinded){
pageY = event.clientY + (document.body.scrolTop || document.documentElement.scrolTop;);
}
});
  • 事件

    • 标准事件监听elem.addEventListener(type, handler, capture)/elem.removeEventListener(type, handler, capture):handler接收保存事件信息的event对象作为参数,event.target为触发事件的对象,handler调用上下文this为绑定监听器的对象,event.preventDefault()取消事件默认行为,event.stopPropagation()/event.stopImmediatePropagation()取消事件传递
    • 老版本IE事件监听elem.attachEvent(‘on’+type, handler)/elem.detachEvent(‘on’+type, handler):handler不接收event作为参数,事件信息保存在window.event中,触发事件的对象为event.srcElement,handler执行上下文this为window使用闭包中调用handler.call(elem, event)可模仿标准模型,然后返回闭包,保证了监听器的移除。event.returnValue为false时取消事件默认行为,event.cancleBubble为true时取消事件传播
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
      var EventUtil = {
    addHandler:function(element,type,handler){
    if(element.addEventListener()){
    element.addEventListener(type, handler,false);
    }else if(element.attachEvent){
    element.attachEvent("on"+type,handler);
    }else{
    element["on"+type] = handler;
    }
    },
    getEvent:function(event){
    return event?event||window.event;
    },
    getTarget:function(event){
    return event.target || event.srcElement;
    },
    preventDefault: function(event){
    if (event.preventDefault()) {
    event.preventDefault();
    }else{
    event.returnValue = false;
    }
    }
    removeHandler:function(element,type,handler){
    if(element.removeEventListener()){
    element.removeEventListener(type, handler,false);
    }else if(element.detachEvent){
    element.detachEvent("on"+type,handler);
    }else{
    element["on"+type] = null;
    }
    },
    stopPropagation:function(event){
    if (event.stopPropagation()) {
    event.stopPropagation();
    }else{
    event.cancelBubble = true;
    }
    }
    }

  • 窗口滚动条偏移量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /**
    * 获取指定window中滚动条的偏移量,如未指定则获取当前window
    * 滚动条偏移量
    *
    * @param {window} w 需要获取滚动条偏移量的窗口
    * @return {Object} obj.x为水平滚动条偏移量,obj.y为竖直滚动条偏移量
    */
    function getScrollOffset(w) {
    w = w || window;
    // 如果是标准浏览器
    if (w.pageXOffset != null) {
    return {
    x: w.pageXOffset,
    y: w.pageYOffset
    };
    }

    // 老版本IE,根据兼容性不同访问不同元素
    var d = w.document;
    if (d.compatMode === 'CSS1Compat') {
    return {
    x: d.documentElement.scrollLeft,
    y: d.documentElement.scrollTop
    }
    }

    return {
    x: d.body.scrollLeft,
    y: d.body.scrollTop
    };
    }
  • 返回指定窗口的视口尺寸

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /**
    * 查询指定窗口的视口尺寸,如果不指定窗口,查询当前窗口尺寸
    **/
    function getViewportSize(w) {
    w = w || window;

    // IE9及标准浏览器中可使用此标准方法
    if ('innerHeight' in w) {
    return {
    width: w.innerWidth,
    height: w.innerHeight
    };
    }

    var d = w.document;
    // IE 8及以下浏览器在标准模式下
    if (document.compatMode === 'CSS1Compat') {
    return {
    width: d.documentElement.clientWidth,
    height: d.documentElement.clientHeight
    };
    }

    // IE8及以下浏览器在怪癖模式下
    return {
    width: d.body.clientWidth,
    height: d.body.clientHeight
    };
    }

css

  • IE6的双倍边距BUG 块元素有浮动和横向的margin,横向margin会被放大2倍
    display: inline
  • IE6下图片下方有空隙产生
    改变html的排版,或者设置img 为display:block,
    或者设置vertical-align 属性为vertical-align:top bottom middle text-bottom都可以解决
  • 3像素文本偏移bug
    当文本与一个浮动元素相邻时,例如:将一个元素向左浮动,并且不希望相邻段落中的文本围绕浮动元素,你也许会在段落上应用一个左外边距,其宽度等于浮动元素的宽度
    解决:

    1
    2
    3
    4
    5
    6
    p{height:1%;//迫使元素拥有布局,拥有布局的元素被限制为矩形,并且出现在浮动元素旁边
    margin-left:0;
    }
    .myFloat{
    margin-right:-3px;
    }
  • IE6 重复字符bug
    在某些情况下,一些列浮动元素的最后一个元素中的最后几个字符会在浮动元素下重复出现(当一系列浮动元素的第一个和最后一个元素之间有多个注释时,前两个注释没有影响,但后续的每个注释会导致两个字符重复出现)
    解决:可以通过设置负右外边距。最安全的:去掉注释

  • “藏猫猫bug”
    一个浮动元素后面跟着一些非浮动元素,然后是一个清理元素,所有这些元素都包含在一个设置了背景颜色或图像的父元素里,如果清理元素碰到了浮动元素,那么中间的非浮动元素看起来消失了,隐藏到了父元素的背景颜色或图像后面,只有在刷新页面时才会重新出现
    解决:给父容器一个明确的“宽度”或“高度”,例如height:1%

    或者:父容器和浮动元素的定位类型positon都设置为“相对”rellative
    
  • 相对容器中的绝对定位
    相对元素没有获得IE内部的haslayout属性,因此不能创建新的上下文,所有绝对元素相对于视口定位
    .container{height:1%;}

  • Chrome支持小于12px 的文字

    1. -webkit-text-size-adjust:none;通过它即可实现字体大小不随终端设备或浏览器影响。是在最新版的谷歌里。已经不在支持这个属性,需要通过css3的transform来解决
    2. span{-webkit-transform:scale(0.8);-o-transform:scale(1); display:inline-block;}
      {webkit-transform:scale(0.8); display:inline-block} //0.8位缩放倍数,具体自己根据实际需求修改,只能缩放可以定义宽高的元素,而span是行内元素,
      {-o-transform:scale(1);}opera现在最新版也是webkit内核,新版本的opera,本来就是10px的字体了
  • display:inline-block 间隙
    真正意义上的inline-block水平呈现的元素间,换行显示或空格分隔的情况下会有间距
    解决:移除空格、使用margin负值、使用font-size:0、letter-spacing、word-spacing
    more
  • overflow: scroll时不能平滑滚动
    -webkit-overflow-scrolling: touch
    more

  • IE 9选择器数量限制问题

  • IE8 resize
    参考

  • css Hack
    为了获得统一的页面效果,需要针对不同的浏览器或不同版本编写特定的CSS样式,这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack~

    • CSS属性前缀法: IE6能识别下划线”“和星号” “,IE7能识别星号” “,但不能识别下划线”“,IE6~IE10都认识”\9”,但firefox前述三个都不能认识。
    • 选择器前缀法:例如 IE6能识别html .class{},IE7能识别+html .class{}或者*:first-child+html .class{}。
    • IE条件注释法:针对所有IE(注:IE10+已经不再支持条件注释): <!--[if IE]>IE浏览器显示的内容 <![endif]-->,针对IE6及以下版本: <!--[if lt IE 6]>只在IE6-显示的内容 <![endif]-->。这类Hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效。
      more