Web前端瀏覽器相容初探
前言
瀏覽器相容是前端開發人員必須掌握的一個技能,但是初入前端的同學或者其他後臺web開發同學往往容易選擇忽略,而形成兩個極端:
1 我最開始都是使用IE6,IE6上沒問題,其它瀏覽器坑爹(多出現與前端後端一起搞的同學,小生2年前就這種狀態,鼓勵人家用ie6.。。。)
2 我要遵循標準,我只要ff就好,IE就是坑爹的玩意,我不必去理他(小生一年前的心態。。。)
現在看來,之前的想法都是不對的,我們誠然應該追求最新的瀏覽器使用最新的技術,但是漸進增強,向後相容的思想一定要有,
因為就現在IE6在中國的份額也是不容小視的。
拋開之前的大道理,我們說點實際的問題,哪次前端面試不問相容性問題?哪次我們又能回答的很好?反正我就沒一次說好的,知不足然後能改,
我前端時間便經過整理形成這篇文章,文章有很多不足,希望各位指正、補充,後面若是能形成一篇較全面的前端相容文章就善莫大焉了!
為什麼會有相容問題?
由於市場上瀏覽器種類眾多,而不同瀏覽器其核心亦不盡相同,所以各個瀏覽器對網頁的解析就有一定出入,這也是導致瀏覽器相容問題出現的主要原因,我們的網頁需要在主流瀏覽器上正常執行,就需要做好瀏覽器相容。
使用Trident核心的瀏覽器:IE、Maxthon、TT;
使用Gecko核心的瀏覽器:Netcape6及以上版本、FireFox;
使用Presto核心的瀏覽器:Opera7及以上版本;
使用Webkit核心的瀏覽器:Safari、Chrome。
而我現在所說的相容性問題,主要是說IE與幾個主流瀏覽器如firefox,google等。
而對IE瀏覽器來說,IE7又是個跨度,因為之前的版本更新甚慢,bug甚多。從IE8開始,IE瀏覽器漸漸遵循標準,到IE9後由於大家都一致認為標準很重要,可以說在相容性上比較好了,但是在中國來說,由於xp的佔有率問題,使用IE7以下的使用者仍然很多,所以我們不得不考慮低版本瀏覽器的相容。
對瀏覽器相容問題,我一般是這樣分類的,HTML,Javascript相容,CSS相容。 其中html相關問題比較容易處理,無非是高版本瀏覽器用了低版本瀏覽器無法識別的元素,導致其不能解析,所以平時注意一點就是。特別是HTML5增加了許多新標籤,低版本瀏覽器有點影響時代進步啊;
javascript相容性問題
在javascript中,各個瀏覽器基本語法差距不大,其相容問題主要出現在各個瀏覽器的實現上,尤其對事件的支援有很大問題,在此我就說說我知道的幾個問題。
① 在標準的事件繫結中繫結事件的方法函式為 addEventListener,而IE使用的是attachEvent
② 標準瀏覽器採用事件捕獲的方式對應IE的事件冒泡機制(即標準由最外元素至最內元素或者IE由最內元素到最外元素)最後標準方亦覺得IE這方面的比較合理,所以便將事件冒泡納入了標準,這也是addEventListener第三個引數的由來,而且事件冒泡作為了預設值。
③ 事件處理中非常有用的event屬性獲得亦不相同,標準瀏覽器是作為引數帶人,而ie是window.event方式獲得,獲得目標元素ie為e.srcElement 標準瀏覽器為e.target
④ 然後在ie中是不能操作tr的innerHtml的
⑤ 然後ie日期函式處理與其它瀏覽器不大一致,比如: var year= new Date().getYear(); 在IE中會獲得當前年,但是在firefox中則會獲得當前年與1900的差值。
⑥ 獲得DOM節點的方法有所差異,其獲得子節點方法不一致。
IE:parentElement parentElement.children Firefox:parentNode parentNode.childNodes childNodes的下標的含義在IE和Firefox中不同,Firefox使用DOM規範,childNodes中會插入空白文字節點。一般可以通過node.getElementsByTagName()來回避這個問題。
當html中節點缺失時,IE和Firefox對parentNode的解釋不同。例如:
<form> <table> <input/> </table> </form> IE:input.parentNode的值為空節點 Firefox:input.parentNode的值為form 解決方法:Firefox中節點沒有removeNode方法,必須使用如下方法 node.parentNode.removeChild(node)
⑦ 關於AJAX的實現上亦有所不同;
就javascript來說,各大瀏覽器之間的差異還是不少的,但是具體我變得這裡都不大關注了,因為我們開發過程中一般都會使用類庫,若是不使用,都會自己積累形成一個類庫,所以就js而言,相容性問題基本解決了。
讓人頭疼的CSS相容
因為之前對css的理解不夠深入,也沒有經過系統的學習,所以一度認為css是前端最難的東西,但真的學習後,才發現css真的很難。。。有很多東西啊!!!
我覺得最讓人頭疼的問題還是CSS問題,因為一點點佈局上的bug,可能導致整個頁面的錯位,在使用者看來這是極不專業的。
現在我就簡要說說我對CSS相容問題的認識: 先說點Hack的知識(真正的高手是不用Hack的,但要成為高手必須通過Hack這一關)
/* CSS屬性級Hack */ color:red; /* 所有瀏覽器可識別*/ _color:red; /* 僅IE6 識別 */ *color:red; /* IE6、IE7 識別 */ +color:red; /* IE6、IE7 識別 */ *+color:red; /* IE6、IE7 識別 */ [color:red; /* IE6、IE7 識別 */ color:red\9; /* IE6、IE7、IE8、IE9 識別 */ color:red\0; /* IE8、IE9 識別*/ color:red\9\0; /* 僅IE9識別 */ color:red \0; /* 僅IE9識別 */ color:red!important; /* IE6 不識別!important 有危險*/ /* CSS選擇符級Hack */ *html #demo { color:red;} /* 僅IE6 識別 */ *+html #demo { color:red;} /* 僅IE7 識別 */ body:nth-of-type(1) #demo { color:red;} /* IE9+、FF3.5+、Chrome、Safari、Opera 可以識別 */ head:first-child+body #demo { color:red; } /* IE7+、FF、Chrome、Safari、Opera 可以識別 */ :root #demo { color:red\9; } : /* 僅IE9識別 */ /* IE條件註釋Hack */ <!--[if IE 6]>此處內容只有IE6.0可見<![endif]--> <!--[if IE 7]>此處內容只有IE7.0可見<![endif]-->
接下來說說一些我知道的BUG:
① css盒模型在IE6下解析有問題,我們知道就width來說,一個塊級元素的magin、padding、boder,width7個屬性的寬度之和,應該等於其父級元素的內容區域(width),而我們一般設定寬度若是未達到其長度,瀏覽器就會重置margin-right的值,將之它們的和等於其值,當然若是我們為margin設定負值,那麼元素的width可能超出其父元素。
在標準下,width為padding所佔區域,但是再ie6中設定width後,其真實width為所設width-其padding與border*2,我一般採用CSShack技術處理
② IE6的雙倍邊距BUG,在塊級元素浮動後本來外邊距10px,但IE解釋為20px,解決辦法是加上display: inline
問題:在IE6下如果某個標籤使用了float屬性,同時設定了其外補丁“margin:10px 0 0 10px”可以看出,上邊距和左邊距同樣為10px,但第一個物件距左邊有20px。
解決辦法:當將其display屬性設定為inline時問題就都解決了。
說明:這是因為塊級物件預設的display屬性值是block,當設定了浮動的同時,還設定了它的外邊距 就會出現這種情況。
也許你會問:“為什麼第二個物件和第一個物件之間就不存在雙倍邊距的BUG”?
因為浮動都有其相對應的物件,只有相對於其父物件的浮動 物件才會出現這樣的問題。
第一個物件是相對父物件的,而第二個物件是相對第一個物件的,所以第二個物件在設定後不會出現問題。
另外在一些特殊佈局中,可能需要組合使用display:block;和display:inline;才能達到預期效果。
當然最壞的情況下,我們就可以使用”margin:10px 0 0 10px;*margin:10px 0 0 10px;_margin:10px 0 0 5px”,
這種“標準屬性;*IE7識別屬性;_IE6識別屬性”HACK方式解決
總結:這個現象僅當塊級物件設定了浮動屬性後才會出現,內聯物件(行級物件)不會出現此問題。並且只有設定左邊距和右邊距的值才會出問題,上下邊距不會出現問題。
<div style="width:200px;height:50px;background:#ccc;"> <div style="width:100px; height:50px;float:left;margin-left:10px; background:#eee;"> </div> </div>
margin雙佈局可以說是IE6下經典的bug之一。產生的條件是:block元素+浮動+margin。
還記得我自認為會css的那個階段,這個問題我經常碰到,會很熟練的用hack解決這個問題,當時還自以為是,洋洋得意。現在看來,當時的自己嫩的就像個 豆芽菜。
真正css厲害的人基本上是不會碰到這個bug的,如果您時不時遇到這個bug,說明您的css還有好一段路要走。
我的體會是越少的浮動,就會越少的程式碼,會有更靈活的頁面,會有擴充套件性更強的頁面。這不多說,歸結為到一定水平了,浮動會用的較少。
另外,您也會避免使用浮動+margin的用法。所以,越後來越不易遇到這種bug。
這裡提一下解決方法,使用hack我是不推薦的,使用hack屬於比初學者稍高一點的層次水平。一個頁面,沒有一個hack,但是各個瀏覽器下表現一致,這才是水平。
使用display:inline;可以解決這個問題。
而為什麼display:inline可以解決這個雙邊距bug,首先是inline元素或inline-block元素是不存在雙邊距問題的。
然後,float:left等浮動屬性可以讓inline元素haslayout,會讓inline元素表現得跟inline-block元素的特性一樣, 支援高寬,垂直margin和padding等,所以div class的所有樣式可以用在這個display inline的元素上。
以上便是我所記得的一些bug,在這裡我再順帶提一下haslayout(IE8廢棄該屬性)。
在IE低版本瀏覽器時基本是表格佈局的時代,幾乎是所有的元素(除內聯元素)都是一個盒子,內容不會超過表格的單元格,表格的單元格也不會超出表格。
在IE6推出後,CSS改變這一假設——因為CSS允許內容超出元素。 因此haslayout這個屬性就誕生了。
在IE6,IE7中,每個元素都有haslayout這個屬性,可以設定為 true 或者 false。
如果設定為true,元素就必須去自我佈局和渲染,因此元素會擴充套件去包含它溢位的內容,例如浮動或沒截斷的單詞。
如果haslayout 沒有被設定成true,那麼元素需依靠某個祖先元素來渲染它。這就是很多的ie bugs誕生的地方。IE瀏覽器下的很多bug都是haslayout = false 引起的,
layout元素有以下特點:
擁有佈局(haslayout=true)元素不會收縮,所以可能會發生文字截斷、消失的現象;
佈局元素對浮動自動清理;
相對定位的元素沒有佈局,這可能導致絕對元素定位偏差;
擁有佈局的元素外邊距不疊加;
滾動時,頁面會有所跳動;
邊框消失
畫素偏差
haslayout不是一個CSS屬性,所以我們不能這樣的來設定它 haslayout:true;
一個元素被設定成haslayout:true將被渲染成一個 having haslayout,
反之同理。 一些元素本身該屬性為true,若是需要觸發,最好的方法是設定其zoom屬性; 哪些元素本身就 haslayout:true
<html>, <body><table>, <tr>, <th>, <td><iframe>, <embed> (non-standard element),
<object>, <applet> <img><hr><input>, <button>, <select>, <textarea>, <fieldset>, <legend>
zoom:1,被認為是最好的觸發Layout的方法,因為它對當前元素沒有影響。 觸發haslayout,相對來說比haslayout=false要簡單。
以下屬性和值將給定一個元素進行佈局
position: absolute float: left or right display: inline-block;width: any value other than auto;
height: any value other than auto;zoom: any value other than normal (*);writing-mode: tb-rl
最後,因為各個瀏覽器對一些元素的預設值設定不一致也會導致表現差異,比如瀏覽器預設字型,預設行高,預設間距等。所以我們一般會為幾個主要元素設定預設值。
結語
以上便是我對瀏覽器相容的簡單認識,但是還是有很多不足的地方,由於技術所限,這裡提出來和各位高手交流,希望在交流學習中和以後工作中積累相關經驗,做出滿足主流瀏覽器的網頁。
相關文章
- IE瀏覽器相容瀏覽器
- 9:瀏覽器相容瀏覽器
- 關於瀏覽器相容瀏覽器
- forEach()相容所有瀏覽器瀏覽器
- 瀏覽器相容性瀏覽器
- web前端進階篇(二) 瀏覽器 WebpackWeb前端瀏覽器
- chrome瀏覽器 json外掛【WEB前端助手】Chrome瀏覽器JSONWeb前端
- 前端檔案下載相容方案(相容主流瀏覽器,包括IE與Safari)前端瀏覽器
- edge瀏覽器相容性設定在哪 新版edge瀏覽器相容模式怎麼弄瀏覽器模式
- 瀏覽器相容以及PostCSS詳解瀏覽器CSS
- 前端面試瀏覽器系列:瀏覽器快取前端面試瀏覽器快取
- 谷歌瀏覽器相容模式怎麼設定 chrome瀏覽器相容模式切換方法介紹谷歌瀏覽器模式Chrome
- 火狐瀏覽器相容模式怎麼設定在哪裡 火狐瀏覽器相容模式設定方法瀏覽器模式
- ie瀏覽器相容模式怎麼設定在哪裡 ie瀏覽器相容模式設定方法瀏覽器模式
- 前端web:瀏覽器靜態資源快取策略前端Web瀏覽器快取
- 精通前端 polyfill ,相容各瀏覽器執行E6語法前端瀏覽器
- win10瀏覽器怎麼設定相容模式_win10瀏覽器相容模式如何新增Win10瀏覽器模式
- 新版edge瀏覽器相容模式怎麼設定 edge瀏覽器相容性設定在哪裡瀏覽器模式
- 相容所有瀏覽器array物件indexOf()方法瀏覽器物件Index
- (16)CSS 擴充:① 瀏覽器相容 | CSSCSS瀏覽器
- element ui 相容低版本瀏覽器UI瀏覽器
- 導航的瀏覽器相容問題瀏覽器
- 360極速瀏覽器相容模式怎麼設定 360極速瀏覽器相容模式設定方法瀏覽器模式
- 好程式設計師前端教程-關於瀏覽器的相容問題程式設計師前端瀏覽器
- web前端瀏覽器物件模型章節Web前端瀏覽器物件模型
- edge瀏覽器找不到相容性檢視設定 新版edge瀏覽器相容模式怎麼設定瀏覽器模式
- 360瀏覽器相容模式怎麼設定 360極速瀏覽器極速相容模式怎麼切換瀏覽器模式
- [BUG反饋]IE瀏覽器,百度瀏覽器,搜狗瀏覽器批量操作功能都不相容!!!!傲遊、火狐、谷歌瀏覽器可以瀏覽器谷歌
- html5多終端瀏覽器相容HTML瀏覽器
- 滑鼠右鍵相容MAC版火狐瀏覽器Mac瀏覽器
- 瀏覽器相容問題處理總結瀏覽器
- 瀏覽器帶你學前端瀏覽器前端
- 手機瀏覽器通過Scheme跳轉APP,相容各種手機瀏覽器瀏覽器SchemeAPP
- win10瀏覽器相容性怎麼設定_win10瀏覽器相容性設定方法Win10瀏覽器
- Web瀏覽器裡的那些事Web瀏覽器
- 瀏覽器極速模式和相容模式差異瀏覽器模式
- 關於UC瀏覽器相容scroll事件問題瀏覽器事件
- 最強悍LoadRunner和瀏覽器相容完美攻略瀏覽器
- 幾款瀏覽器相容性測試工具瀏覽器