• 前端兼容性问题总结


    HTML 篇

    样式兼容性问题

    <!-- IE 按 Edge 模式渲染 -->
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <!-- IE 8 9 10 按 IE7 模式渲染 -->
    <meta http-equiv="X-UA-Compatible" content="IE=Emulate7" />

    怪异模式

    怪异模式是没有遵守 W3C 规范的一种兼容模式,其中的 width 是包括 contentWidth, 左右padding, 左右border 在内的全部范围(height 也一样),类似于 box-sizing: border-box;,而且 table 的 font-size 不能从父元素继承。以下情况会触发浏览器怪异模式(Quirks Mode):

    • 没写 DOCTYPE 触发怪异模式
    • <!DOCTYPE ...>前加<?xml version="1.0" encoding="utf-8" ?>, IE6 下会触发怪异模式
    • <!DOCTYPE ...>前加入<!-- keep IE7 in Quirks Mode -->, IE7进入怪异模式
    • <!DOCTYPE ...>前有任何非空字符,会在IE6 下会触发怪异模式
    • <!DOCTYPE ...>前有 XML ,在IE7 下不会触发怪异模式,但不能有其他非空字符

    检查document.compatMode,可以查看浏览器工作在哪个模式:值BackCompat为怪异模式,值CSS1Compat为标准模式

    display:inline-block 元素间有间隙

    <!-- 以下的 li 元素是 display: inline; 类型的 -->
    <!-- 这样写元素之间有间隙 -->
    <ul>
      <li>apple</li>
      <li>banana</li>
      <li>pineapple</li>
      <li>peach</li>
      <li>orange</li>
    </ul>
    <!-- 换个写法解决问题-->
    <ul>
      <li>apple</li><li>
      banana</li><li>
      pineapple</li><li>
      peach</li><li>
      orange</li>
    </ul>

    IE可能出现的文档样式短暂失效问题

    <head>
        <!-- meta部分 -->
        <title></title>
        <!-- 可能的script部分 -->
        <script type="text/javascript"></script>   <!-- 关键:添加一个空标签 -->
        <!-- link部分 -->
    </head>

    css 篇

    双倍间距问题

    /*一下代码在 IE6 中会出现双倍间距*/
    #box{
      float: left;
      margin: 10px;
    }
    
    //解决方法
    #box{
      float: left;
      margin: 10px;
      display: inline;
    }

    错位问题

    /*IE6中,这样的多个盒子并列时会发生向下偏移,应该对偏移的盒子添加负 margin-top 进行修正*/
    .box{
      float: left;
    }

    IE6 奇数宽高问题

    IE6 中盒子的宽(width) 和高(height)设置为奇数时会有 bug,尽量设置为偶数即可。

    IE6 Peekaboo Bug

    一个 div#top 中加入一个 div#float 向左浮动,然后加入一个或多个 div, 直到清除浮动为止:

    <style>
    #top{
        border: dotted 2px black;
        background: #eee;    /*top有背景*/
    }
    #float{
        height: 196px;
         196px;
        border: 2px solid red;
    }
    .border{
        border: 2px solid green;
    }
    .clear{
        clear: both;
        border: 2px solid blue;
    }
    </style>
    <body>
        <div id="top">
            <div id="float">float div</div>
            <!-- 这以下在 IE6 中不能正常显示 -->
            <div class="border">inside-div text!</div>
            <div class="border">inside-div text!</div>
            <!-- 这以上在 IE6 中不能正常显示 -->
            <div class="clear">clear div</div>
        </div>
    </body>

    解决方法,给 #top 一个 height 或 width :

    #top{
        height: 300px;
    }

    盒子坍塌

    这个问题比较普遍,在盒内层元素设置外边距时会发生

    /*发生盒子坍塌*/
    #box{
      height: 300px;
    }
    #box .inner-box{
      margin:20px;
    }
    
    /*修正*/
    #box{
      height: 300px;
      margin-top: -20px;
    }
    #box .inner-box{
      margin:20px;
    }

    文字大小

    字体大小在不同浏览上不一致。例如font-size:14px,在 IE 中的实际行高是16px,下面有3px留白;在 Firefox 中的实际行高是17px,下面有3px留白,上边1px留白;在 opera 中就更不一样了。解决方式统一指定行高 line-height

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

    另外,我们会遇到 font-size:62.5% 这样的定义,为了把默认的 16px 映射为 10px, 这样1em = 10px 更利于计算。

    去除元素默认边距

    有很多元素默认带有边距,对我们排版很不利。但利用通配符*去除边距存在性能问题,所以用下面语句清除默认边距

    body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{
      margin: 0;
      padding: 0;
    }

    低版本 IE 高度限定失效

    一般的元素指定高度属性 height 可以固定该元素高度,但在低版本 IE 中无法固定元素高度,该元素高度依然会被内容撑开,需要注意。(宽度也一样)

    IE6 不支持 png 透明效果

    解决方式用滤镜

    #box{
      _background: none;
      filter: progid:DXImageTransForm.Microsoft.AlphaImageLoader(src='路径');
    }

    Firefox 的宽度问题

    Firefox浏览器会的 body 比其他浏览器的 body 宽度小1个像素,注意设置其子元素(尤其 float 元素大小,防止排版混乱。

    IE6中的吞吃问题

    IE6 中为上下2个 div 中的上一个地址设置背景时,下一个 div 也会带有背景。类似的还有 overflow:scroll 时,出现的滚动条不完整。应该 分别对在上方的 div 和滚动条不完整的 div 加 zoom: 1样式。

    IE6 图片格式问题

    IE6 中的图片默认存在边框,应统一去除。同时图片下方会有空隙,用 font-size解决

    img{
      border: none;
      font-size: 0;
    }

    IE中无法定义1px高度这样的小盒子

    IE6 中的空元素高度不能低于19px,解决方式有四种: 
    1. 在元素中插入空注释 <!----> 
    2. 在元素中插入空格 &nbsp; 
    3. 加入 css: overflow:hidden; 
    4. 加入 css: font-size: 0;

    IE6 z-index 失效

    当父元素已设置 z-index 属性后,子元素的 z-index 会失效。

    IE6中 select 始终高于 div

    浮层 div 出现时隐藏 select,浮层 div 消失时再显示 select。

    让 chrome 支持小于 12px 的字体

    #box{
      font-size: 8px;
      -webkit-text-size-adjust: none;
    }
    /* 但是,上面这个方法 chrome27 以后就不能用了。但我们可以用 css3 解决这个问题 */
    #box{
      font-size: 12px;
      -webkit-transform: scale(0.75);
    }

    CSS Hack

    兼容性属性设置,注意书写顺序:优先写高等级浏览器支持方式、优先写支持浏览器多的方式

    /*以 color 属性为例,注意书写顺序*/
    #box{
      color: #f00;   //所有浏览器都支持
      color: #0f0 !important;   //只有 IE6 无效
      color: #00f9;  //所有 IE 都有效
      color: #ff00;  //IE8+ 有效
      color: #f0f90; //IE9+ 有效
      *color: #fff;  //仅 IE6, IE7 有效
      #color: #0ff;  //仅 IE6, IE7 有效
      +color: #800;  //仅 IE6, IE7 有效
      -color: #008;  //只有 IE6 有效
      _color: #080;  //只有 IE6 有效
    }

    由于后定义的属性覆盖先定义的属性,所有上面设置最后的效果为: 
    IE6 为 #080 
    IE7 为 #800 
    IE8 为 #ff0 
    IE9,10 为 #0f0 
    其他 为 #f00

    javascript 篇

    innerText 和 innerContent

    1. innerText 和 textContent 的作用相同
    2. innerText IE8之前的浏览器支持
    3. innerContent 老版本的Firefox支持
    4. 新版本的浏览器两种方式都支持

    和以上四种情况完全一致的还有parentElement(老IE)和parentNode

    获取兄弟节点/元素的兼容性问题

    ie8以前不支持previousElementSiblingnextElementSibling,以及诸如此类带有Element的元素属性。利用previousSibling和 
    nextSibling等不带Element的属性实现如下:

    // 获取下一个紧邻的兄弟元素
    function getNextElement(element){
      var ele = element;
      if(ele.nextElementSibling) return ele.nextElementSibling;
      do{
        ele = ele.nextSibling;
      }while(ele && ele.nodeType !== 1);
      return ele;
    }
    
    // 获取上一个紧邻的兄弟元素
    function getPreviousElement(element){
      var ele = element;
      if(ele.perviousElementSibling) return ele.perviousElementSibling;
      do{
        ele = ele.perviousSibling;
      }while(ele && ele.nodeType !== 1);
      return ele;
    }
    
    // 获取第一个子元素
    function getFirstElement(parent){
      if(parent.firstElementChild) return parent.firstElementChild;
      var ele = parent.firstChild;
      while(ele && ele.nodeType !== 1) ele = ele.nextSibling;
      return ele;
    }
    
    // 获取最后一个子元素
    function getLastElement(parent){
      if(parent.LastElementChild) return parent.LastElementChild;
      var ele = parent.lastChild;
      while(ele && ele.nodeType !== 1) ele = ele.perviousSibling;
      return ele;
    }
    
    // 获取所有兄弟元素
    function sibling(ele){
      if(!ele) return null;
    
      var elements = [ ];
      var el = ele.previousSibling;
      while(el){
      if(el.nodeType === 1)
        elements.push(el);
      el = el.previousSibling;
      }
      el = element.nextSibling;
      while(el){
      if(el.nodeType === 1)
        elements.push(el);
      el = el.nextSibling;
      }
      return elements;
    }

    其它DOM操作

    IE中有一些很好用的 DOM 方法,但是其他浏览器却没有,比如: 
    ele.swapNode(anotherEle)用来交换节点; 
    ele.removeNode()删除当前节点; 
    ele.insertAgjacentHTML('position','HTMLText')ele.insertAgjacentHTML('position',ele) 用来插入节点;

    部分实现方式写在下面:

    //实现swapNode方法
    if(window.Node && !Node.prototype.swapNode){
      Node.prototype.swapNode = function(node){
        var nextSibling = this.nextSibling;
        var parentNode = this.parentNode;
        node.parentNode.replaceChild(this, node);
        parentNode.insertBefore(node, nextSibling);
      }
    }
    //实现removeNode
    if(window.Node && !Node.prototype.removeNode){
      Node.prototype.removeNode = function(){
        this.parentNode.removeChild(this);
      }
    }
    
    //insertAdjacentHTML和insertAdjacentElement可以用insertBefore代替
    //由于有现成方法替换,这里不写具体实现了

    js 操作 css 兼容性

    //透明度
    //非IE方法
    ele.style.opacity = 0.2;  //0-1
    //IE
    ele.style.filter = "alpha(opacity=100)";
    
    //float属性
    //非IE
    ele.style.float = "left";
    //IE
    ele.style.cssFloat = "left";

    Array方法

    array.filter();

    if (!Array.prototype.filter)
    {
      Array.prototype.filter = function(fun /*, thisArg */)
      {
        "use strict";
        if (this === void 0 || this === null)
          throw new TypeError();
        var t = Object(this);
        var len = t.length >>> 0;
        if (typeof fun !== "function")
          throw new TypeError();
        var res = [];
        var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
        for (var i = 0; i < len; i++){
          if (i in t){
            var val = t[i];
            if (fun.call(thisArg, val, i, t))
              res.push(val);
          }
        }
        return res;
      };
    }

    array.forEach();

    if (!Array.prototype.forEach) {
      Array.prototype.forEach = function(callback, thisArg) {
        var T, k = 0;
        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;
        while (k < len) {
          var kValue;
          if (k in O) {
            kValue = O[k];
            callback.call(T, kValue, k, O);
          }
          k++;
        }
        return undefined;
      };
    }

    注册事件

    标准的绑定方法有两种,addEventListener和attachEvent前者是标准浏览器支持的API,后者是IE8以下浏览器支持的API:

    //例如给一个button注册click事件
    var el = document.getElementById('button');  //button是一个<button>元素
    var handler = function(e){alert("button clicked.");};
    if(el.addEventLister){
        el.addEventListener("click", handler,false);
    }
    if(el.attachEvent){
        el.attachEvent("onclick", handler);
    }

    需要注意的是: 
    - addEventLister的第一个参数事件类型是不加on前缀的,而attachEvent中需要加on前缀; 
    - addEventLister中的事件回调函数中的this指向事件元素target本身,而attachEvent中的事件回调函数的this指向的是window; 
    - addEventLister有第三个参数,true表示事件工作在捕获阶段,false为冒泡阶段(默认值:false)。而attachEvent只能工作在冒泡阶段; 
    - 解除事件方法标准方法removeListen(),在IE8中,对应使用detachEvent()。注意,他们和上面的注册方法一一对应,不能混用; 
    - 阻止默认事件标准方法 event.preventDefault(), 在IE8中,使用 event.returnValue = false; 
    - 阻止冒泡的方法 event.stopPropagation(), 在IE8中,使用 event.cancelBubble = true; 
    - 老版本 IE 中,事件函数内部的 this 不是被监听元素本身,而是 window 。故应该使用 call 改变 this 指向。

    事件对象

    • e.eventPhase 事件阶段,IE8及以前不支持,因为那时不支持捕获
    • e.target 始终是触发事件的对象。IE8以前用srcElement
    • ie8以前用window.event获得事件对象,而不是回调函数的参数e
    function(e){}
        return e || window.event;  
    }
    
    // 兼容target
    function(e){
      target = e.target || e.srcElement;
      //do something else
     }

    获取鼠标在页面上的位置

    ie8以前没有完整的位置属性,部分属性需要通过已有的属性计算得到:

    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
    var pageX = e.pageX || e.x || e.clientX + scrollLeft;
    var pageY = e.pageY || e.y || e.clientY + scrollTop;

    获取键盘事件的键值

    var keyCode = e.keyCode || e.which;

    取消用户的文本的选择,移动端很常用

    window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

    使不支持h5的浏览器支持h5标签

    <!--[if IE]>
    <style>
      article, aside, footer, header, nav, section, details, menu, figure {
        display: block;
      }
      canvas, progress, audio, video {
        display: inline-block;
      }
      progress {
        vertical-align: baseline;
      }
      audio:not([controls]) {
        display: none;
        height: 0;
      }
      mark {
        background-color: #ff0;
        color: #000;
      }
    </style>
    <script>
    (function() {
      if(!/*@cc_on!@*/0)
        return;
      var e = "abbr, article, aside, audio, bb, canvas, datagrid, datalist, details, dialog, eventsource, figure, footer, header, hgroup, mark, menu, meter, nav, output, progress, section, time, video".split(', ');
      var i = e.length;
      while(i--) {
        document.createElement(e[i]);
      }
    })();
    </script>
    <![endif]-->

    Ajax 兼容问题

    //定义一个 XMLHttpRequest 对象
    var xhr;
    if(XMLHttpRequest){
      xhr = new XMLHttpRequest();    //chrome, safari, opera, firefox
    } else if(ActionXObject){
      try{
        xhr = new ActionXObject("Msxml2.XMLHTTP");   //IE 中 Msxml 插件
      }catch(e){
        xhr = new ActionXObject("Microsoft.XMLHTTP");   //IE
      }
    }

    综合篇

    处理 html 和 css 编码不一致问题

    在 web.config 中写以下代码

    <system.web><globalization fileEncoding="utf-8" resquestEncoding="utf-8" responseEncoding="utf-8" culture="zh-CN"  /></system.web>
  • 相关阅读:
    WindowsPhone7 经典3D游戏《刺客信条》评测
    WPF案例 — 展厅触摸屏展示系统
    Silverlight三维柱状图3D饼图的Silverlight图表组件案例
    应聘Silverlight讲师(全职或兼职均可)
    WPF案例之生产线控制器管理系统
    Silverlight 5 Beta 版发布日期确定
    《银光志Silverlight 3.0开发详解与最佳实践》发行第三版总销量过万册
    微软Silverlight5发布会提供线上注册
    Silverlight WebOS案例2.0版本(基于Silverlight4开发的Web操作系统)
    长年承接WP7游戏和WP7软件外包
  • 原文地址:https://www.cnblogs.com/qq666666/p/7883049.html
Copyright © 2020-2023  润新知