1. 程式人生 > >處理瀏覽器相容所遇到的問題總結(一)

處理瀏覽器相容所遇到的問題總結(一)

注意:因為瀏覽器問題,重新定義Array.prototype.indexOf…等函式時,一定要注意符合原始定義,不要隨便用別的實現方式定義,否則可能會影響外掛呼叫

之前開發專案時,前端除錯都是以google chrome瀏覽器為準,現需處理瀏覽器相容問題,現將遇到的問題總結如下:

一. firefox 瀏覽器div下的table無水平滑動條

<div id="tableContainer" style="height:420px;width:100%;"  class="table-responsive">
<table id="demoTable" class="table table-condensed table-bordered"
style="width:1650px;">

原因:bootstrap中添加了樣式

.table{max-width:100%;}

解決方法:去掉table中的table類屬性。

二. IE下無法用AJAX表單上傳檔案

解決方法:(1)用form表單post提交上傳檔案
(2)將<meta http-equiv="x-ua-compatible" content="ie=7" />
替換為<meta http-equiv="X-UA-Compatible" content="IE=Edge" />

<meta http-equiv="X-UA-Compatible"
content="IE=7" />

無論頁面是否包含 指令,均使用 Windows Internet Explorer 7 的標準渲染模式。

<meta http-equiv="X-UA-Compatible" content="IE=8" /> 

開啟 IE8 的標準渲染模式,但由於本身 X-UA-Compatible 檔案頭僅支援 IE8 以上版本,因此等同於冗餘程式碼。

<meta http-equiv="X-UA-Compatible" content="edge" /> 

Edge 模式通知 Windows Internet Explorer 以最高級別的可用模式顯示內容,這實際上破壞了“鎖定”模式。

三. 問題:當點選螢幕下方的按鈕,按鈕點選事件處理後,螢幕滑動條會跳回頂部,導致不能及時看到處理結果,要看到結果還是要將滑動條重新拉至下方。

解決方法:(1)在滑鼠點選按鈕後,先獲取螢幕當前滑動條的位置

// 由於document.documentElement.scrollTop和document.body.scrollTop在標準模式或者是奇怪模式下都只有一個會返回有效的值,所以都加上也不會有問題

g_beforeClickScrollTop = document.body.scrollTop + document.documentElement.scrollTop;

(2)之後在點選事件處理完畢後,使用之前儲存的位置將滑動條的位置恢復至點選時的位置。

//20160615 螢幕滑動條 回到點選圓圈按鈕時的位置 如果不加此語句 統計圖載入完後 螢幕滾動條會上移至頂部

document.body.scrollTop = g_beforeClickScrollTop;
document.documentElement.scrollTop = g_beforeClickScrollTop;

處理時出現了 chrome瀏覽器只支援document.body.scrollTop,而IE和firefox只支援
document.documentElement.scrollTop的情況,以上的處理方法是對這三個瀏覽器相容的。

四. IE瀏覽器在 a href中有中文引數時,顯示亂碼,firefox和chrome瀏覽器顯示正常

之前程式碼
thymeleaf

<a th:href="${'project/aaaaaaa?id='+item.id +'&amp;name=' + item.name }" th:text="${item.name}" title="點選進入" target="_blank">

javascript:

'<td Value="' + e.name + '"><a href="/project/aaaaaa?id=' + e.id + '&amp;name=' + e.name + '" title="點選進入專案雷達" target="_blank">' + e.name + '</a></td>'

更改後代碼
thymeleaf

<a th:href="@{project/aaaaaaa(id = ${item.id},                name = ${item.name})}" th:text="${item.name}" title="點選進入" target="_blank">

@{…}連結url的表示式。th:href="@{/xxx/aa.do(id=${o.id})",會自動進行url-encoding的處理。@{…}內部可以是需要計算的表示式,比如:

th:href=”@{'/details/'+${user.login}(orderId=${o.id})}"

javascript:

'<td Value="' + e.name + '"><a href="/project/aaaaaa?id=' 
+ e.id + '&amp;name=' + encodeURI(e.name) + '" title="點選進入專案雷達" target="_blank">' + e.name + '</a></td>'

五. IE瀏覽器無法識別jquery的$物件

原因: 今天在用jQuery實現web上面的一個刪除功能的時候,發現通過chrome刪除完全正常,但是在eclipse的內建瀏覽器中卻不能刪除,感覺有些莫名其妙,找了半天原因。
後面發現:
1、eclipse中的內建瀏覽器實際上呼叫的是系統中的ie,然後我在ie中測試了一下,果然如此,和eclipse內建瀏覽器中顯示的一樣,不能刪除;
2、我的ie瀏覽器是ie8,然而我用的jQuery確實2.0版本的,jQuery從2.0版開始不再支援IE6、IE7和IE8,這就是問題所在;
3、將jQuery版本換成2.0版本以下,問題解決。

解決方案:根據不同的瀏覽器載入不同版本的jquery

//方式一
<!--[if !IE]><!-->
 <script src="../../static/jquery/2.1.4/jquery-2.1.4.min.js"
            th:src="@{/jquery/2.1.4/jquery-2.1.4.min.js}"></script>
 <!--<![endif]-->

  <!--[if IE]><!-->
 <script src="../../static/jquery/1.11.0/jquery-1.11.0.min.js"
            th:src="@{/jquery/1.11.0/jquery-1.11.0.min.js}"></script>
 <!--<![endif]-->

//方式二
<script language="javascript"> 
if(navigator.appName == "Microsoft Internet Explorer") 
{ 
   if(navigator.appVersion.match(/7./i)=='7.') 
   { 
  //是IE7,不載入dojo.js 
   }else{ 
     //載入dojo.js 
  document.write("<script src=\"dojo.js\">"+"</scr"+"ipt>"); 
   } 
} 
</script> 
把上面這段js放到你引用dojo.js的地方就ok了

附帶判斷所用瀏覽器的方法:
方式一:

<!--[if !IE]><!--> 除IE外都可識別 <!--<![endif]-->
<!--[if IE]> 所有的IE可識別 <![endif]-->
<!--[if IE 6]> 僅IE6可識別 <![endif]-->
<!--[if lt IE 6]> IE6以及IE6以下版本可識別 <![endif]-->
<!--[if gte IE 6]> IE6以及IE6以上版本可識別 <![endif]-->
<!--[if IE 7]> 僅IE7可識別 <![endif]-->
<!--[if lt IE 7]> IE7以及IE7以下版本可識別 <![endif]-->
<!--[if gte IE 7]> IE7以及IE7以上版本可識別 <![endif]-->
<!--[if IE 8]> 僅IE8可識別 <![endif]-->
<!--[if IE 9]> 僅IE9可識別 <![endif]-->

方式二:

1、判斷瀏覽器是否為IE 
        document.all ? 'IE' : 'others':在IE下document.all值為1,而其他瀏覽器下的值為0; 
        navigator.userAgent.indexOf("MSIE")>0 ? 'IE' : 'others':navigator.userAgent是描述使用者代理資訊。 
        navigator.appName.indexOf("Microsoft") != -1 ? 'IE' : 'others':navigator.appName描述瀏覽器名稱資訊。 
2、判斷IE版本 
        navigator.appVersion.match(/6./i)=="6." ? 'IE6' : 'other version':在已知是IE瀏覽器的情況下,可以通過此方法判斷是否是IE6; 
        navigator.userAgent.indexOf("MSIE 6.0")>0 ? 'IE7' : 'other version':同上; 
        navigator.appVersion.match(/7./i)=="7." ? 'IE7' : 'other version':在已知是IE瀏覽器的情況下,可以通過此方法判斷是否是IE7; 
        navigator.userAgent.indexOf("MSIE 7.0")>0 ? 'IE7' : 'other version':同上; 
        navigator.appVersion.match(/8./i)=="8." ? 'IE8' : 'other version':在已知是IE瀏覽器的情況下,可以通過此方法判斷是否是IE8; 
        navigator.userAgent.indexOf("MSIE 8.0")>0 ? 'IE8' : 'other version':同上。

六. 將web應用地址貼上到IE位址列中無法開啟

這裡寫圖片描述
解決方案:
其它瀏覽器是沒問題的,自然不是網路問題。其實後來找出來是因為IE前面需要加”http://”才能訪問,其它瀏覽器會預設加上這個,但IE不會

七. IE8不識別javascript的Array.indexOf方法

解決方案
針對ie8及以下版本,自己建立indexOf函式。

//20161123 add 針對IE不支援indexOf的問題新增
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(searchElement, fromIndex) {
        var k;
        if (this == null) {
            throw new TypeError('"this" is null or not defined');
        }
        var O = Object(this);
        var len = O.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = +fromIndex || 0;
        if (Math.abs(n) === Infinity) {
            n = 0;
        }
        if (n >= len) {
            return -1;
        }
        k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
        while (k < len) {
            if (k in O && O[k] === searchElement) {
                return k;
            }
            k++;
        }
        return -1;
    };//indexOf
}

八. IE8不識別側邊隱藏欄外掛BootSideMenu.js中的DOM元素的classList屬性

解決方案:
重寫此屬性

//20161123 add 針對IE不支援indexOf的問題新增
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(searchElement, fromIndex) {
        var k;
        if (this == null) {
            throw new TypeError('"this" is null or not defined');
        }
        var O = Object(this);
        var len = O.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = +fromIndex || 0;
        if (Math.abs(n) === Infinity) {
            n = 0;
        }
        if (n >= len) {
            return -1;
        }
        k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
        while (k < len) {
            if (k in O && O[k] === searchElement) {
                return k;
            }
            k++;
        }
        return -1;
    };//indexOf
}

//20161123 為解決IE無法獲取classList屬性的問題 新增此函式  重寫classList
    Object.defineProperty(Element.prototype, 'classList', {
        get: function() {
            var self = this, bValue = self.className.split(" ")

            bValue.add = function (){
                var b;
                for(i in arguments){
                    b = true;
                    for (var j = 0; j<bValue.length;j++)
                        if (bValue[j] == arguments[i]){
                            b = false
                            break
                        }
                    if(b)
                        self.className += (self.className?" ":"")+arguments[i]
                }
            }
            bValue.remove = function(){
                self.className = ""
                for(i in arguments)
                    for (var j = 0; j<bValue.length;j++)
                        if(bValue[j] != arguments[i])
                            self.className += (self.className?" " :"")+bValue[j]
            }
            bValue.toggle = function(x){
                var b;
                if(x){
                    self.className = ""
                    b = false;
                    for (var j = 0; j<bValue.length;j++)
                        if(bValue[j] != x){
                            self.className += (self.className?" " :"")+bValue[j]
                            b = false
                        } else b = true
                    if(!b)
                        self.className += (self.className?" ":"")+x
                } else throw new TypeError("Failed to execute 'toggle': 1 argument required")
                return !b;
            }

            bValue.contains = function(value) {
                return !!~self.className.split(/\s+/g).indexOf(value);
            }

            return bValue; 
        },
        enumerable: false
    });

九. IE8和之前的瀏覽器不支援CSS3 media queries,你可以在頁面中新增css3-mediaqueries.js來解決這個問題。

<!--[if lt IE 9]>
    <script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->

mediaquery用於實現螢幕的自適應顯示,適用場景為:
預設情況下,頁面容器的寬度是980px,這個尺寸優化了大於1024px的解析度。Media query用來檢查 viewport 寬度,如果小於980px他會變為窄屏顯示模式,頁面佈局將會以流動的寬度代替固定寬度。如果 viewport 小於650px,他會變為mobile顯示模式,內容、側邊欄等內容會變為單獨列布局方式,他們的寬度佔滿螢幕寬度。
示例:

@media screen and (max-width: 980px) {

    #pagewrap {
        width: 95%;
    }

    #content {
        width: 60%;
        padding: 3% 4%;
    }

    #sidebar {
        width: 30%;
    }
    #sidebar .widget {
        padding: 8% 7%;
        margin-bottom: 10px;
    }

}


@media screen and (max-width: 650px) {

    #header {
        height: auto;
    }

    #searchform {
        position: absolute;
        top: 5px;
        right: 0;
    }

    #main-nav {
        position: static;
    }

    #site-logo {
        margin: 15px 100px 5px 0;
        position: static;
    }

    #site-description {
        margin: 0 0 15px;
        position: static;
    }

    #content {
        width: auto;
        float: none;
        margin: 20px 0;
    }

    #sidebar {
        width: 100%;
        float: none;
        margin: 0;
    }

}

十. js中innerHTML與innerText的用法與區別

<div id="test">
   <span style="color:red">test1</span> test2
</div>

在JS中可以使用:

test.innerHTML:

  也就是從物件的起始位置到終止位置的全部內容,包括Html標籤。

  上例中的test.innerHTML的值也就是
  “<span style="color:red">test1</span> test2 ”

test.innerText:

  從起始位置到終止位置的內容, 但它去除Html標籤

  上例中的text.innerTest的值也就是“test1 test2”, 其中span標籤去除了。

test.outerHTML:

  除了包含innerHTML的全部內容外, 還包含物件標籤本身。

<div id="test"><span style="color:red">test1</span> test2</div>

特別說明:

  innerHTML是符合W3C標準的屬性,而innerText只適用於IE瀏覽器,因此,儘可能地去使用innerHTML,而少用innerText,如果要輸出不含HTML標籤的內容,可以使用innerHTML取得包含HTML標籤的內容後,再用正則表示式去除HTML標籤,下面是一個簡單的符合W3C標準的示例:

<a href="javascript:alert(document.getElementById('test').innerHTML.replace(/<.+?>/gim,''))">無HTML,符合W3C標準</a>

由於innerText並非W3C標準屬性,因此我們無法在FireFox中使用它(修正:FF45+已經支援innerText屬性),一般情況下我們可以使用textContent來代替。

十一. IE8不支援js中動態建立button後,再通過btnObj.type設定type屬性時

    var btnObj = document.createElement("button");
    //btnObj.type="button";
    //IE不支援type
    if(!btnObj){
        btnObj.setAttribute('type', 'button'); 
    }

針對非 input 元素,各瀏覽器中,既可以把對元素屬性的改變寫在顯示元素(insertBefore 或 appendChild)之前,也可以在其後。

針對 input 元素,為了相容 IE,type 屬性寫在顯示元素(insertBefore 或 appendChild)之前,其它屬性寫在其後。
例項(相容性)
document.createElement建立的<button>的type屬性為只讀
測試程式碼中避開了type的預設值,因為<button>的type屬性在IE下的預設值是button,而在其他瀏覽器預設是submit 。我們平時在使用時,建議顯式的宣告type屬性。

// 建立input 
var iptEl = document.createElement('input'); 
iptEl.type = 'password';  // 避免預設值 
iptEl.name = 'damon'; 

document.body.appendChild(iptEl); 

// 建立button 
var btnEl = document.createElement('button'); 
btnEl.type = 'reset';  // IE下這裡報錯了 
btnEl.name = 'damon'; 

document.body.appendChild(btnEl); 

alert(document.getElementsByTagName('input')[0].type +','+ 
    document.getElementsByTagName('button')[0].type);

解決方案
MSDN有一段說明:
As of Microsoft Internet Explorer 5, the type property is read/write-once, but only when an input element is created with the createElement method and before it is added to the document.
即只有document.createElement建立的input元素,在其增加到DOM樹之前允許對type屬性進行一次更改。但從實際情況來看並非如此,這個僅有的一次設定type的機會在建立時就用掉了。從上面的測試結果看,這個問題直到IE9才修復。

針對IE,document.createElement(tag)中,tag可以是帶有屬性的字串,建立時即將type和name寫上即可。

Attributes can be included with the sTag as long as the entire string is valid HTML.
對其他的現代瀏覽器(Chrome、Safari等)使用setAttribute即可,或者使用document.createAttribute建立屬性節點,再通過setAttributeNode加到元素節點上。

方法一:

var btnEl; 

try { 
    btnEl = document.createElement('<BUTTON name=damon type=reset></BUTTON>'); 
} catch(e){} 

if(! btnEl) { 
    btnEl = document.createElement('button'); 

    btnEl.setAttribute('type', 'reset'); 
    btnEl.setAttribute('name', 'damon'); 
} 

document.body.appendChild(btnEl); 
alert(document.getElementsByTagName('button')[0].type +','+ 
    document.getElementsByTagName('button')[0].name);

方法二:

var btnEl; 

try { 
    btnEl = document.createElement('<BUTTON name=damon type=reset></BUTTON>'); 
} catch(e){} 

if(! btnEl) { 
    btnEl = document.createElement('button'); 

    var aType = document.createAttribute('type'); 
    var aName = document.createAttribute('name'); 

    aType.value = 'reset'; 
    aName.value = 'damon'; 

    btnEl.setAttributeNode(aType); 
    btnEl.setAttributeNode(aName); 
} 

document.body.appendChild(btnEl); 
alert(document.getElementsByTagName('button')[0].type +','+ 
    document.getElementsByTagName('button')[0].name);

十二. IE8不支援html5 canvas

(1)針對IE8不支援html5 canvas的功能需要在html檔案head中新增js檔案:

<!-- 針對IE瀏覽器不相容canvas的情況 -->
<!--[if IE]><!-->
<script src="/explorerCanvas/excanvas.js"></script>
<script src="/explorerCanvas/html5shiv.js"></script>
<!--<![endif]-->

使用canvas時:

var canvas=document.getElementById(canvasEleId);
//針對IE瀏覽器不相容canvas的情況
//var cxt=canvas.getContext("2d");
var cxt=null;

if (typeof window.G_vmlCanvasManager!="undefined") {                                    canvas = window.G_vmlCanvasManager.initElement(canvas);    
cxt=canvas.getContext("2d");
}else { 
cxt=canvas.getContext("2d");
 }

(2)IE8下使用display:none 樣式隱藏的div裡的canvas,不顯示所畫圖形,原因是:
excanvas是利用IE支援的VML物件來模擬Canvas的繪圖的。
excanvas.js首先建立Canvas物件,然後把所有有關Canvas的繪圖操作都用相應的VML物件來實現,所以我們在低版本的ie中也能看到Canvas影象了。

原html中程式碼為:

<div id="divContainer" style="display: none;">
<canvas class="myCanvasCls" id="mycanvas" width="30" height="30"></canvas>
</div>

經excanvas處理後為:

<div id="divContainer" style="display: none;">
<canvas class="myCanvasCls" id="mycanvas" style="width: 30px; height: 30px;" height="30" width="30" getContext="function getContext() {
   return this.context_ || (this.context_ = new CanvasRenderingContext2D_(this));}" context_="[object Object]">
  <div style="position: absolute; width: 0px; height: 0px; overflow: hidden;">
    <g_vml_:shape style="position: absolute; width: 10px; height: 10px;">
    <g_vml_:fill/>
  </div>
  <div style="position: absolute; filter: alpha(opacity=0); BACKGROUND-COLOR: red; width: 0px; height: 0px; overflow: hidden;"/>
 </canvas> 
 </div>

因為如果在樣式檔案或頁面檔案程式碼中直接用display:none對元素進行了隱藏,載入頁面後,在沒有通過js設定樣式使元素顯示的前提下,使用js程式碼會無法正確獲得該元素的一些屬性,比如offSetTop,offSetLeft等,返回的值會為0,通過js設定style.display來使元素顯示後才能正確獲得這些值。
canvas下的div的width和height一開始被初始化為了0,即使之後divContainer的display置為了”“,canvas下的影象也無法顯示。

解決方法:
先設定divContainer的display置為了”“,再對canvas畫圖,之後再將divContainer的display置為了”none”.

(3)如(2)中所示,由於canvas下的div,position為absolute, 所以需要將其父元素canvas的position設為relative,這樣才能保證canvas下div裡的圖形顯示在原本canvas定義的位置離裡,而不是絕對的始終顯示在螢幕的某一位置。

(4)IE8畫實心圓時,角度要用弧度(0,Math.PI*2), 不要使用(0,360)

 var canvas=document.getElementById(canvasId);
//針對IE瀏覽器不相容canvas的情況
//var cxt=canvas.getContext("2d");
var cxt=null;
if (typeof window.G_vmlCanvasManager!="undefined") {                                         canvas=window.G_vmlCanvasManager.initElement(canvas);
cxt=canvas.getContext("2d");
}else {    
cxt=canvas.getContext("2d");
}
//alert("cxt: " + cxt + "; Math.PI*2: " + Math.PI*2);
//畫一個實心圓
cxt.beginPath();
cxt.fillStyle="#ddd";//填充顏色,預設是黑色
/*arc(x, y, radius, startAngle, endAngle, counterclockwise) x,y是中心點座標 counterclockwise弧沿著圓周的逆時針方向(TRUE)還是順時針方向(FALSE)遍歷。*/                            cxt.arc(15,15,10,0,Math.PI*2,false); 
cxt.closePath(); 
cxt.fill();//畫實心圓

十三. IE8不支援rem,不支援input:checked選擇器

rem是CSS3中新增加的一個單位值,他和em單位一樣,都是一個相對單位。不同的是em是相對於元素的父元素的font-size進行計算;rem是相對於根元素html的font-size進行計算。這樣一來rem就繞開了複雜的層級關係,實現了類似於em單位的功能。

Rem的使用
em是相對於其父元素來設定字型大小的,這樣存在一個問題,進行任何元素設定之前,都需要知道其父元素的大小,在我們多次使用時,就會帶來無法預知的錯誤風險。
而rem是相對於根元素<html>,這樣就意味著,我們只需要在根元素確定一個參考值,這個參考值設定為多少,完全可以根據需求來定。

例如:瀏覽器預設的字號16px,如下px與rem的轉換關係:
| px | rem |
| 12 | 12/16 = .75 |
| 14 | 14/16 = .875 |
| 16 | 16/16 = 1 |
| 18 | 18/16 = 1.125 |
| 20 | 20/16 = 1.25 |
| 24 | 24/16 = 1.5 |
| 30 | 30/16 = 1.875 |
| 36 | 36/16 = 2.25 |
| 42 | 42/16 = 2.625 |
| 48 | 48/16 = 3 |

將css中input:checked 改為 input[checked] 即可

十四. IE瀏覽器不支援修改select元素的innerHTML屬性

解決方法(參考文章):
1. 如果堅持要使用innerHTML屬性,需使用一個div元素封裝select,然後設定div物件的innerHTML屬性。
2. 利用option元素

<html>
    <head>
        <title>Example</title>
        <script type="text/javascript">
<!--
function fill_select1() {
    for ( var i = 0; i < 100; i++) {
        select1.options[i] = new Option(i, i);
    }
}

function fill_select2() {
    var sOpts = "<select>";
    for ( var i = 0; i < 100; i++) {
        sOpts += '<option value="' + i + '">' + i + '</option>';
    }
    select2.outerHTML = sOpts + "</option>";
}

function fill_select3() {
    for ( var i = 0; i < 100; i++) {
        var oOption = document.createElement("OPTION");
        oOption.text = "Option: " + i;
        oOption.value = i;
        document.all.select3.add(oOption)
    }
}
//-->
</script>
    </head>
    <body>
        <h2>
            SELECT Box Population
        </h2>
        <select id=select1 name=select1></select>
        <input type="button" value="Populate with options list" id="button1"
            name="button1" onclick="fill_select1();">
        <br />
        <br />
        <select id="select2" name="select2"></select>
        <INPUT type="button" value="Populate with outerHTML" id="button2"
            name="button2" onclick="fill_select2();">
        <br />
        <br />
        <select id="select3" name="select3"></select>
        <input type="button" value="Populate with using createElement"
            id="button3" name="button3" onclick="fill_select3();">
    </body>
</html>

十五 css hack

彈性佈局flex對IE8不相容,用css hack解決

body{
        margin: 0;
        height: 100%;
        background: #bfd1e1;
        font-size:13px;
        font-family: 微軟雅黑;
        display: flex;
        justify-content: center;
        align-items: center;
        display: -webkit-flex;
        -webkit-justify-content: center;
        -webkit-align-items: center;

        /* \0 IE8/IE9/IE10都生效,是IE8/9/10的hack*/
        position:absolute\0;
        top:20%\0;
        left:32%\0;

}
只在IE下生效
<!--[if IE]>
這段文字只在IE瀏覽器顯示
<![endif]-->

只在IE6下生效
<!--[if IE 6]>
這段文字只在IE6瀏覽器顯示
<![endif]-->

只在IE6以上版本生效
<!--[if gte IE 6]>
這段文字只在IE6以上(包括)版本IE瀏覽器顯示
<![endif]-->

只在IE8上不生效
<!--[if ! IE 8]>
這段文字在非IE8瀏覽器顯示
<![endif]-->

非IE瀏覽器生效
<!--[if !IE]>
這段文字只在非IE瀏覽器顯示
<![endif]-->

方式二:類內屬性字首法
屬性字首法是在CSS樣式屬性名前加上一些只有特定瀏覽器才能識別的hack字首,以達到預期的頁面展現效果。

這裡寫圖片描述

說明:在標準模式中

"-"減號是IE6專有的hack
"\9" IE6/IE7/IE8/IE9/IE10都生效
"\0" IE8/IE9/IE10都生效,是IE8/9/10的hack
"\9\0" 只對IE9/IE10生效,是IE9/10的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有效等等

demo如下

<script type="text/javascript">  
    //alert(document.compatMode);  
</script>  
<style type="text/css">  
body:nth-of-type(1) .iehack{  
    color: #F00;/* 對Windows IE9/Firefox 7+/Opera 10+/所有Chrome/Safari的CSS hack ,選擇器也適用幾乎全部Mobile/Linux/Mac browser*/  
}  
.demo1,.demo2,.demo3,.demo4{  
    width:100px;  
    height:100px;  
}  
.hack{  
/*demo1 */  
/*demo1 注意順序,否則IE6/7下可能無法正確顯示,導致結果顯示為白色背景*/  
    background-color:red; /* All browsers */  
    background-color:blue !important;/* All browsers but IE6 */  
    *background-color:black; /* IE6, IE7 */  
    +background-color:yellow;/* IE6, IE7*/  
    background-color:gray\9; /* IE6, IE7, IE8, IE9, IE10 */  
    background-color:purple\0; /* IE8, IE9, IE10 */  
    background-color: