<!-- 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 ...>
前加<?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
<!-- 如下的 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>
<head> <!-- meta部分 --> <title></title> <!-- 可能的script部分 --> <script type="text/javascript"></script> <!-- 關鍵:添加一個空標籤 --> <!-- link部分 --> </head>
/*一下代碼在 IE6 中會出現雙倍間距*/ #box{ float: left; margin: 10px; } //解決方法 #box{ float: left; margin: 10px; display: inline; }
/*IE6中,這樣的多個盒子並列時會發生向下偏移,應該對偏移的盒子添加負 margin-top 進行修正*/ .box{ float: left; }
IE6 中盒子的寬(width) 和高(height)設置爲奇數時會有 bug,儘可能設置爲偶數便可。html
一個 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; }
通常的元素指定高度屬性 height 能夠固定該元素高度,但在低版本 IE 中沒法固定元素高度,該元素高度依然會被內容撐開,須要注意。(寬度也同樣)canvas
解決方式用濾鏡
#box{ _background: none; filter: progid:DXImageTransForm.Microsoft.AlphaImageLoader(src='路徑'); }
Firefox瀏覽器會的 body 比其餘瀏覽器的 body 寬度小1個像素,注意設置其子元素(尤爲 float 元素大小,防止排版混亂。
IE6 中爲上下2個 div 中的上一個地址設置背景時,下一個 div 也會帶有背景。相似的還有 overflow:scroll
時,出現的滾動條不完整。應該 分別對在上方的 div 和滾動條不完整的 div 加 zoom: 1
樣式。
IE6 中的圖片默認存在邊框,應統一去除。同時圖片下方會有空隙,用 font-size解決
img{ border: none; font-size: 0; }
IE6 中的空元素高度不能低於19px,解決方式有四種:
1. 在元素中插入空註釋 <!---->
2. 在元素中插入空格
3. 加入 css: overflow:hidden;
4. 加入 css: font-size: 0;
當父元素已設置 z-index 屬性後,子元素的 z-index 會失效。
浮層 div 出現時隱藏 select,浮層 div 消失時再顯示 select。
#box{ font-size: 8px; -webkit-text-size-adjust: none; } /* 可是,上面這個方法 chrome27 之後就不能用了。但咱們能夠用 css3 解決這個問題 */ #box{ font-size: 12px; -webkit-transform: scale(0.75); }
兼容性屬性設置,注意書寫順序:優先寫高等級瀏覽器支持方式、優先寫支持瀏覽器多的方式
/*以 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
和以上四種狀況徹底一致的還有parentElement(老IE)和parentNode
ie8之前不支持previousElementSibling
和nextElementSibling
,以及諸如此類帶有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; }
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代替 //因爲有現成方法替換,這裏不寫具體實現了
//透明度 //非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.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之前用srcElementfunction(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();
<!--[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]-->
//定義一個 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 } }
在 web.config 中寫如下代碼
<system.web><globalization fileEncoding="utf-8" resquestEncoding="utf-8" responseEncoding="utf-8" culture="zh-CN" /></system.web>