前端兼容性问题总结

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):javascript

  • 没写 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为标准模式css

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,尽可能设置为偶数便可。html

IE6 Peekaboo Bug

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

<style> #top{ border: dotted 2px black; background: #eee; /*top有背景*/ } #float{ height: 196px; width: 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 :node

#top{ height: 300px; }

盒子坍塌

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

/*发生盒子坍塌*/ #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-heightweb

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

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

去除元素默认边距

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

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 中没法固定元素高度,该元素高度依然会被内容撑开,须要注意。(宽度也同样)canvas

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: #00f\9; //全部 IE 都有效 color: #ff0\0; //IE8+ 有效 color: #f0f\9\0; //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>
相关文章
相关标签/搜索