一種讓 IE6/7/8 支援 media query 響應式設計的方法

來源:互聯網
上載者:User

標籤:

在不同的瀏覽器寬度下使用不同的 CSS 聲明,常見的方案是使用 media query,但這個方案不支援 IE9 以下瀏覽器。

國外比較流行的 使用者介面架構 bootstrap v3 版本中使用 media query 技術實現了柵格布局 ,但要相容 IE8 的話,( IE6/7 沒有中國佔比那麼高,所以不用相容)需要引入 Respond.js 的方案。

 

該方案的原理分以下 4 步:

1、在樣式 link 之後,載入 respond.js ,該指令碼會擷取在他之前出現的 link 節點到一個數組

2、發送 ajax 請求重新擷取 link 數組中 css 檔案常值內容

3、通過分析常值內容中 @media 類聲明,重新計算並應用相關樣式

4、在 window.resize 時,觸發第 3 步邏輯

 

這裡的問題點有兩個:

1、第 2 步是否會造成重複的請求消耗?

2、如果 css 靜態資源存放網域名稱與當前頁面不同,勢必會遇到 js 同源策略的限制,如何突破跨域問題?

 

問題 1 比較好回答,基本包括 IE 在內的所有瀏覽器都會對 GET 請求進行緩衝,由於在第 1 步的時候瀏覽器已經請求過所有的 CSS 檔案,因此在第 2 步 ajax 的時候會直接使用本機快取,不會造成效能損耗。但由於需引用一個 respond.proxy.gif 來 hack IE 路徑問題,可能會造成一個額外的請求損耗。

 

問題 2 確實存在,Respond.js 通過 iframe proxy file 的方案突破了同源策略,詳細的講解可參考這篇文章《Respond.js讓IE6-8支援CSS3 Media Query》或自行百度相關JS跨域知識。但在 Respond.js 情境中會造成兩個問題:

1、由於 iframe 的建立是非同步,respond.proxy.js 無法阻塞渲染,勢必會造成頁面樣式的閃動(先應用了預設樣式,第 3 步樣式分析完畢後,又重新應用一次樣式)

2、由於 iframe proxy file 在 css 資源請求完成時的事件無法主動回調(子iframe無法訪問非同源父視窗),而是通過父視窗的一個定時器不斷讀取子視窗 window.name 值來實現被動通訊,因此樣式的渲染就存在進一步的延遲。

 

如果使用情境無法接收問題 2 所帶來的負面影響(有情懷的前端工程師都會把靜態資源部署到一個獨立網域名稱,以提升網頁效能,而且也無法接受頁面出現明顯的重繪這種體驗損失),則需要考慮其他方案(另外 Respond.js 項目作者已經有幾年沒有維護了,部分BUG還沒修複 )。本文就此問題發散出一個基於 SASS + JS 的解決方案,以供參考。思路如下:

 

1、通常螢幕的解析度寬度是符合一定規範的,而PC端網站柵格布局的常見寬度是可以窮舉的:1024px、1280px、1440px、1600px、 1920px

2、在樣式中,針對不同的瀏覽器寬度,我們可以複寫多條樣式規則,例如 body{} 、.w1280px body{} 、.w1440px body{},達到個人化的目的

3、當 window.resize 時,動態在 html 節點上改變預設好的寬度 className ,例如寬度 width = 1620px 時,滿足 width > 1600px && width < 1920px ,因此 html.classList.add(‘w1600px‘)

 

以上方法十分直觀,IE6/7/8 使用以上方案,其他支援 media query 的瀏覽器則使用 @media only screen and (min-width: 1620px)  的 css 樣式方案。對於樣式維護性的問題(寫一大坨 @media 和 .w1440px body 之類的相同樣式肯定不利於維護),我們通過 SASS mixin 來解決,具體代碼參考以下樣式:

 

@mixin mediaWidth($min-width: 1024px, $max-width: null) {    $widthSet: (1024px, 1280px, 1440px, 1600px, 1920px);    $selector: ();    @if $max-width {        @media only screen and (min-width: $min-width) and (max-width: $max-width){             @content;         }    } @else {        @media only screen and (min-width: $min-width) {            @content;         }    }    @each $item in $widthSet {        @if $max-width {            @if $item >= $min-width and $item < $max-width {                $selector: append($selector, unquote(‘.w#{$item} &‘), ‘comma‘);            }        } @else {            @if $item >= $min-width{                $selector: append($selector, unquote(‘.w#{$item} &‘), ‘comma‘);            }        }    }    #{$selector}{        @content;    }}body{    width: 1024px;    background-color: red;    @include mediaWidth(1024px) {        width: 1024px;        background-color: orange;    }    @include mediaWidth(1280px, 1440px) {        width: 1280px;        background-color: green;    }    @include mediaWidth(1600px) {        width: 1600px;        background-color: blue;    }}

 

以上 SASS 編譯之後的 CSS 為:

 

body {    width: 1024px;    background-color: red;}@media only screen and (min-width: 1024px) {    body {        width: 1024px;        background-color: orange;   }}.w1024px body, .w1280px body, .w1440px body, .w1600px body, .w1920px body {    width: 1024px;    background-color: orange;}@media only screen and (min-width: 1280px) and (max-width: 1440px) {    body {        width: 1280px;        background-color: green;   }}.w1280px body {    width: 1280px;    background-color: green;}@media only screen and (min-width: 1600px) {    body {        width: 1600px;        background-color: blue;   }}.w1600px body, .w1920px body {    width: 1600px;    background-color: blue;}

 

問題一:如果項目中沒用到 SASS 怎麼辦?

從實際項目經驗來看,SASS 的引入可以大幅提高樣式檔案的維護性,而且不會對前端項目流程帶來任何影響,因為你可以直接用編輯器的編譯工具在儲存檔案時同步編譯出 CSS 檔案,例如 sublime text 的 sass build 和 build on save 外掛程式,更不用說 sass 命令列、compass、grunt、gulp 之類的工具了。

 

問題二:如果不會 SASS 怎麼辦?

學就是了,看看這個就知道有多簡單了《SASS用法指南》。

 

以上程式碼範例,參看此 demo:http://yekai.net/demo/ie-media-query.html

 

一種讓 IE6/7/8 支援 media query 響應式設計的方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.