一种让 IE6/7/8 支持 media query 响应式设计的方法_html/css_WEB-ITnose

WBOY
Release: 2016-06-24 11:37:05
Original
1191 people have browsed it

在不同的浏览器宽度下使用不同的 CSS 声明,常见的方案是使用 media query,但这个方案不支持 IE9 以下浏览器。

国外比较流行的 UI 框架 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

 

以上方法十分直观,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;    }}
Copy after login

以上 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;}
Copy after login

 

问题一:如果项目中没用到 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

 

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template