ie兼容响应式布局的实现总结 和 针对ie浏览器的CSS

参考链接:http://zhidao.baidu.com/link?url=bQioDKMnG_eQoE6dCxzd2hPtMyiB7phu6hBdOupn1Pjk1hV-ItXFZS5GDUBoH5qrfi9LXkUoSciXTiGN36G6LK

参考链接:http://blog.sina.com.cn/s/blog_601b97ee0101aszo.html


ie浏览器hack
.demo {padding:10px;padding:9px\9; /* all ie */padding:8px\0; /* ie8-9 目前应用于IE8的单独hack,情况比较少 */*padding:5px; /* ie6-7 */+padding:7px; /* ie7 */_padding:6px; /* ie6 */
}这是所有ie的hack了,360用的ie内核,跟本机的ie有关系


虽然说响应式设计的理想状态是,需对pc/移动各种终端进行响应;但是现实是高分辨率的pc端与手机终端屏幕相差太大,像电商这样有大量图片和文字信息的同时排版要求精准的页面,设计一个同时适应高分辨率pc又适合小尺寸的手机终端是挑战;同时高分辨率下pc页面信息量巨大,对于手机端用户是否需要,也许会造成带宽浪费;再者手机终端和pc终端的用户操作习惯也相差甚大,这种多图多信息量要求精准的页面,设计出来恐怕会是2个完全不同的版本,也许各自维护更方便。由于业务形态原因,随着用户分辨率的提高,1024×768已不再是主流,宽屏用户比例越来越大,因此我们的响应式考虑如何充分利用PC用户设备上更多空间而设计。下图为淘宝用户的屏幕分辨率和浏览器比例,鉴于ie8-浏览器目前占比约70%,mediaquery的ie8-兼容迫于现实还是要做,泪……

media query简介

miediaquery有2种引入方式:

1.link标签方式

<link "stylesheet" type="text/css"media="screen" href="sans-serif.css">
<link "stylesheet" type="text/css"media="print" href="serif.css">

2.css方式

@mediascreen {* { font-family: sans-serif }
}

媒体类型有很多种:‘aural’, ‘braille’, ‘handheld’, ‘print’, ‘projection’,‘screen’, ‘tty’, ‘tv’、‘embossed’、‘speech’、’3d-glasses’,但最常用的是screen和print,对于前端们来讲最常用的应该只有screen了。应用于所有媒体类型可以用all,省略不写默认就是all。media query支持很多表达式,常用的如下,完整的查看这里:

@mediaall and (min-width: 400px) and (max-width: 700px) {}
@mediaall and (orientation: portrait) {   }
@mediaand (min-device-width: 800px) { }

利用media query可以轻松实现不同屏幕宽度时切换不同的页面布局,但是很不幸ie8及以下都还不支持mediaquery,于是开始了下面的media query兼容之旅……

目前实现media query ie兼容的库比较成熟的有respond.js和css3-mediaqueries-js;它们各有优劣,respond.js 压缩后1k,只实现了mediaquery中最常用的min-widthmax-width的兼容;css3-mediaqueries-js基本实现了所有css3规范中的mediaquery特性的兼容,所以导致压缩有16k,测试反馈其性能远低于respond.js;不过确实一淘首页2次响应式设计均只需用到max-width和min-width,Modernizr 和 H5BP也均推荐使用respond.js,下面具体看看它们的实现吧

respond.js源码分析

使用方式

官方demo地址:http://scottjehl.github.com/Respond/test/test.html

1.在css中正常用 min/max-width media queries
    @mediascreen and (min-width: 480px){
        ...stylesfor 480pxand up go here
    }
2.引入respond.min.js,但要在css的后面(越早引入越好,在ie下面看到页面闪屏的概率就越低,因为最初css会先渲染出来,如果respond.js加载得很后面,这时重新根据mediaquery解析出来的css会再改变一次页面的布局等,所以看起来有闪屏的现象)

实现思路

  • 1.把head中所有的css路径取出来放入数组
  • 2.然后遍历数组一个个发ajax请求
  • 3.ajax回调后仅分析response中的mediaquery的min-width和max-width语法,分析出viewport变化区间对应相应的css块
  • 4.页面初始化时和window.resize时,根据当前viewport使用相应的css块。
window.matchMedia = window.matchMedia ||(function(doc, undefined){var bool,docElem = doc.documentElement,refNode = docElem.firstElementChild || docElem.firstChild,//fakeBody required forfakeBody= doc.createElement_x('body'),div     = doc.createElement_x('div');div.id = 'mq-test-1';div.style.cssText = "position:absolute;top:-100em";fakeBody.style.background = "none";fakeBody.appendChild(div);return function(q){div.innerHTML= '­';docElem.insertBefore(fakeBody,refNode);bool= div.offsetWidth == 42;docElem.removeChild(fakeBody);return{ matches: bool, media: q };};
})(document);
//检测是否支持mediaquery,检测css是否有效的方法都差不多,创建一个元素应用该css后检测元素宽度,然后清除该元素。
<pre name="code" class="css">.......
if( !!href &&isCSS && !parsedSheets[ href ] ){//selectivizr exposes css through the rawCssText expandoif(sheet.styleSheet &&sheet.styleSheet.rawCssText) {//sheet.styleSheet.rawCssText看不懂,原来是方便selectivizr和respond.js联用,http://selectivizr.com/tests/respond///selectivizr的作用是CSS3 selectors forIE;约定将原csstext放在styleSheet的link上的扩展属性rawCssText上;这里如果联用selectivizr可以少次ajax请求translate(sheet.styleSheet.rawCssText, href, media );parsedSheets[href ] = true;}else {if((!/^([a-zA-Z:]*\/\/)/.test( href ) && !base)||href.replace( RegExp.$1, "").split( "/" )[0] ===win.location.host ){requestQueue.push({href:href,media:media});}}
}
.......

 

其余的代码就是ajax实现和translate media query的max-widthmin-width的逻辑了;可以看出这里必须依赖ajax请求css路径才能得到css文件中的mediaquery的内容,那ajax的跨域问题就要解决了;由于我们的静态资源都是要放cdn的,respond.js也给出了跨域方法,即引入代理页面。

//把cross-domain/respond-proxy.html放到cdn上
//把cross-domain/respond.proxy.gif放到当前域服务器上
"http://externalcdn.com/respond-proxy.html"id="respond-proxy" rel="respond-proxy" />"/path/to/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />"/path/to/respond.proxy.js">

这里ajax跨域实现是通过代理页面将获取到的css,再通过window.name通信实现;如在respond.proxy.js中

function checkFrameName() {varcssText;try{cssText= iframe.contentWindow.name;varnow = new Date().getTime(),useTime = now - initTime;alert('获取css耗时:'+useTime + 'ms');}catch(e) { }if(cssText) {……//销毁之前用于通信的iframe,后续回调callbackcallback(cssText);}else{win.setTimeout(checkFrameName,100);}
}
win.setTimeout(checkFrameName, 500);//500ms后确认内部iframe的name值是否传递过来,后续再更新当前viewport该用的css。

因为实现跨域代理的问题,初始化页面时应用上全部css耗时较长,以下光测试从开始执行该js文件到css取回调用之前的耗时为500ms-515ms之间(每次刷新结果不一样).

测试结果发现,刷新页面后会有明显的闪屏(以该测试demo为例,一开始页面背景是黑色的,这是默认css中的,跨域js执行完成后分析出mediaquery中的该viewport尺寸下应该应用red的背景,所以又变成红色),间隔时间为500ms以上。所以体验不是很好,而且该场景中ajax跨域目前已经没有更好的实现方式,500ms间隔的闪屏避免不了。

同时因为是ajax请求css,所以会因为响应式而额外产生一个请求,好在之前css请求过一遍,这次ajax请求是读取浏览器缓存中的.


respond.js总结

  • 优点:压缩后仅1k,不跨域时性能ok,只需引入respond.js通用易用
  • 缺点:仅支持mediaquery的min-width和max-width(用于响应式够用);支持跨域,虽然配置有点麻烦,实现跨域代价高而且有闪屏体验欠佳。

css3-mediaqueries-js源码分析

css3-mediaqueries-js官方文档和demo都没有,相对于respond.jscss3-mediaqueries-js支持几乎所有的media query的语法,访问测试demo

实现逻辑

其实现逻辑和respond.js差不多,只是更加支持的mediaquery更加全面,同时支持内联style,支持各种宽度单位(em|ex|px|in|cm|mm|pt|pc),但是这里的初始化是在domready后执行,为了让用户感觉不出页面有闪屏(之前应用初始化样式然后js提取mediaquery中的样式再覆盖一遍)现象,这里的实现是先将html移出可视区域外,等解析完mediaquery后再重置回来,但实际目测感觉稍有闪屏(当然这里的测试是测试body背景色,移出可视区域外不管用,当然绝大部分响应式场景是适用的),实现如下:

//prevent jumping of layout by hiding everything beforepainting 先将html移出可视区域外
var docEl =document.documentElement;docEl.style.marginLeft= '-32767px';//make sure it comes back after a while 异常处理,万一获取mediaquerycss失败,重置回来
setTimeout(function (){docEl.style.marginTop = '';
},20000);……// return visibility after media queries are tested生效后重新可见
cssHelper.addListener('cssMediaQueriesTested', function() {//force repaint in IE by changing widthif(ua.ie) {docEl.style.width= '1px';}setTimeout(function() {docEl.style.width= ''; // undowidthdocEl.style.marginLeft= ''; // undohidevarnow = new Date().getTime();varuseTime = now - initTime;alert('mediaquery生效时间:'+useTime+'ms');},0);//remove this listener to prevent following executioncssHelper.removeListener('cssMediaQueriesTested',arguments.callee);
});

其余实现和respond.js基本一致,也需要使用ajax,所以css3-media-queries.js本身不支持跨域,当然非要支持跨域也可以,也可以像respond.js一样使用代理页面跨域即可,但也会出现闪屏的现象。还是先看看不跨域情况下,大多数人为什么选择respond.js,主要原因还是完美支持的mediaquery特性导致压缩后16K,下载和执行时间都逊于respond.js.

css3-mediaqueries-js总结

  • 优点:1、基本支持所有css3中的media query语法
  • 缺点:1、不支持跨域(如cdn),就算支持了跨域也存在闪屏现象;2、和respond.js对比性能较差

全局切换class

因为css/js需要放到cdn上面,需要跨域,css3-mediaqueries-js不支持跨域,respond.js支持跨域但是实现跨域后性能较差,有闪屏体验也差,而且配置麻烦,不方便各个业务通用。对比respond.js和css3-mediaqueries-js可知,实现响应式应用min-width和max-width足矣;同时模拟mediaquery的效果只需要在2个关键时间点根据viewport切换css(初始化页面时和window.resize)即可。所以可以选择切换csslink,可以动态切换css块,也可以切换class

  • 切换csslink(优点:逻辑清晰;缺点:增加请求数,维护麻烦,如修改一个模块涉及到3个尺寸的响应,至少需要改3个文件)
"stylesheet" type="text/css"media="screenand (max-width: 990px)" href="respond750.css&uuot;>
stylesheet"type="text/css" media="screen and(max-width: 1200px)"href="respond990.css">

  • 切换内联css块(respond.js和css3-mediaqueries-js就是通过js分析出mediaquery然后自动根据当前viewport切换css块,这个理想环境下是最好的,自动分析只管写mediaquery,但是依赖ajax获取css内容,跨域实现成本高体验也不好)
  • 全局切换class(特别是初始化页面时最好在页面内容未开始渲染之前切换class,不然会出现像韩国naver购物频道在宽屏时刷新效果,刷新时内容由中间向外偏),特定viewport用特殊全局class标记,响应式样式继承在该class下,实现大致如下:

实现方式

@mediascreen and (min-width: 990px) {.content{width:990px;color:red;}
}
@mediascreen and (min-width: 1200px) {.content{width:1200px;color:green;}
}
.w990 .content {width: 990px;color: red;
}
.w1200 .content {width: 1200px;color: green;
}
"w990">
"content">content

全局切换class这种方式维护也是个问题,首先是js分散2处,body最上方切换全局class,domready时window.resize时切换class,同时响应式尺寸增加时,需要改变js判断条件;再看css的维护,mediaquery一份,加全局class一份相同的,维护需要同时修改2次,初期media query几十行也能接受,但是后来改版mediaquery几百行,这样维护成本就大大增加了,全局class和media querycopy相同的代码引入less解决,使用方法如下:

#channels {.w1200(){.etao-channels{padding:170px 0 0 30px;li{margin-right:25px;}}}.w990(){.etao-channels{padding:25px 0 0 15px;li{margin-right:8px;}}.w750(){.etao-channels{padding:5px 00 5px;li{margin-right:5px;}a{color:#333;}}}
}
/*这样只需维护上面一处代码即可*/
#channels > .w1200;
@media (max-width:1119px){#channels> .w990;
}
@media (max-width:989px){#channels> .w750;
}
.w990{#channels> .w990;
}
.w750{#channels> .w750;
}

目前 一淘新首页采用以上方法维护,支持1200px、990px、750px三个尺寸的响应,不得不承认维护成本还是偏高,欢迎各种改进建议,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276258.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

group by 保留哪一条数据_使用R语言绘制一维数据统计图总结

加载数据 绘制茎叶图 绘制直方图 绘制概率密度曲线 绘制小提琴图 绘制箱线图 绘制小提琴图箱线图 集中趋势统计 分散程度 apply的使用加载数据模拟数据下载library(tidyverse) cjb <- read.csv("/home/wy/Downloads/cjb.csv",header TRUE,stringsAsFactors FALS…

npm安装和Vue运行

一、开始&#xff1a; 下载地址&#xff1a;http://nodejs.cn/download/ 下载安装&#xff1a; 直到 二、打开CMD,检查是否正常 在安装目录里新增两个文件夹 然后运行命令&#xff1a;如下图&#xff1a; npm config set prefix "D:\InstallSoftWare\nodejs\node_global&q…

Scott 32 岁前端年终总结,探寻另一种可能

今年一年都是飞快 这 10 年编程好时光&#xff0c;花费在不经意间&#xff0c;而立的第三年也即将用完&#xff1a;23 到 26 岁&#xff0c;花在了阿里&#xff0c;从入门到职业迷茫&#xff0c;27 到 29 岁&#xff0c;花在了创业&#xff0c;从热血到倒闭还钱&#xff0c;30 …

跨页数据传递的两种方式

选择具有PostBackUrl属性的三个控件Button、LinkButton、ImageButton。PostBackUrl属性的值就是投递的页面URL。 要在接收页面按对象的方式接收投递页面的表单中的值有两种方式&#xff1a; 1、PreviousPage.FindControl(“控件变量名”)&#xff0c;这个方法返回的是Control类…

嵌入式操作系统 NuttX 5.0 发布

Nuttx 是一个实时嵌入式操作系统&#xff08;RTOS&#xff09;&#xff0c;它有一个小巧是在微控制器的环境中使用。这是完全可扩展&#xff0c;从小型&#xff08;8位&#xff09;至中型嵌入式&#xff08;32位&#xff09;系统。它的目的还 在于要完全符合标准&#xff0c;完…

Windows下Mysql 的安装和卸载

2019独角兽企业重金招聘Python工程师标准>>> 一、安装 1、下载zip文件 2、解压&#xff0c;在bin目录下新建my.ini [mysql] # 设置mysql客户端默认字符集 default-character-setutf8 [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 basedirC:\Program Fil…

现在学前端还来得及吗?总听人说饱和了

“前端已经饱和了&#xff0c;现在学前端没有前途了”每次听到这种论调我都气不打一处来。自己技艺不精&#xff0c;然后就说市场饱和了。是&#xff0c;现在的确不是那个会切个图&#xff0c;懂点htmlCSS就能找到工作的年代了。现在对前端的技术要求稍微高了点&#xff0c;但这…

DotNetNuke 5 C#版本解读之2--HTTP Modules

在前面文章里说明了DNN的架构&#xff0c;下面这个图应该说是更加能够全面的让你去了解它的结构&#xff1a; 如果你是个asp.net新手建议你看看前面这部分&#xff0c;因为它会向你介绍什么是http module,以及其他的一些概念。我想通过你读这篇文章来明白asp.net的机制&#xf…

用框架的你,可能早已忽略了这些事件API

DOMContentLoaded&#xff0c;load&#xff0c;beforeunload&#xff0c;unloadHTML 页面的生命周期包含三个重要事件&#xff1a;DOMContentLoaded —— 浏览器已完全加载 HTML&#xff0c;并构建了 DOM 树&#xff0c;但像 <img> 和样式表之类的外部资源可能尚未加载完…

原来 Clipboard 还能复制图像?原理是什么

在写了 这个 29.7 K 的剪贴板 JS 库有点东西&#xff01; 这篇文章之后&#xff0c;收到了小伙伴提的两个问题&#xff1a;1.clipboard.js 这个库除了复制文字之外&#xff0c;能复制图像么&#xff1f;2.clipboard.js 这个库依赖的 document.execCommand API 已被废弃了&…

JavaScript 元编程

大家好&#xff0c;我是若川。今天给分享一篇来自freecodecamp的好文。我是freecodecamp杭州社区组织者之一&#xff0c;有一群小伙伴一起组织线下分享活动&#xff0c;不过2020年我们杭州社区几乎没有活跃&#xff0c;我也没有什么贡献。另外&#xff0c;我的公众号「若川视野…

手写一个合格的前端脚手架

为什么我们需要一套脚手架为什么我们需要一套脚手架&#xff0c;它能帮助我们解决哪些痛点问题。•前端项目配置越来越繁琐、耗时&#xff0c;重复无意义的工作•项目结构不统一、不规范•前端项目类型繁多&#xff0c;不同项目不同配置&#xff0c;管理成本高•脚手架也可以是…

第一篇cnblog!

本人才疏学浅&#xff0c;终于通过了cnblog的审核&#xff0c;兴奋之余&#xff0c;发表感言——不容易啊&#xff01;在我的博闻里面&#xff0c;随笔类当然就是技术类的比较多的&#xff0c;特别是实例类的。理论类的大部分放在文章板块&#xff0c;本人e文特别好(哈哈&#…

利用JMeter进行压力测试(1)(转)

转自&#xff1a;http://www.cnblogs.com/game-over/archive/2010/01/08/1642685.html压力测试以软件响应速度为测试目标&#xff0c;尤其是在较短时间内大量并发用户的同时访问时&#xff0c;软件的性能和抗压能力。 JMeter是一款开源的压力测试工具&#xff0c;目前最新Rele…

Git 内部原理图解——对象、分支以及如何从零开始建仓库

我们中的许多人每天都在使用 git&#xff0c;但是有多少人知道它的内部是怎么运作的呢&#xff1f;例如我们使用 git commit 时发生了什么&#xff1f;提交&#xff08;commit&#xff09;与提交之间保存的是什么&#xff1f;两次提交之间难道只是文件的差异&#xff08;dif…

Google, 请不要离开我们!

虽然我是.net阵营, 力挺Silverlight, 但是我真心希望谷歌留在中国, 如果她能够靠谈判求的言论自由的权利, 那将对中国的拥有自由信仰的一族产生重大的影响. 谷歌离开了中国, 不是她想抛弃中国市场, 而是中国决策者背叛了人性. 在此留下 Google 2010年1月14日的logo, 智慧的幽默…

28岁自学3年前端成功转行的励志故事

为什么转行因为混得不好。在成为程序员之前&#xff0c;我干过很多工作。由于学历的问题&#xff08;高中&#xff09;&#xff0c;我的工作基本上都是体力活。包括但不限于&#xff1a;工厂普工、销售&#xff08;没有干销售的才能&#xff09;、搬运工、摆地摊等&#xff0c;…

usb 驱动

usb 驱动学习总结&#xff1a; usb 采用分层的拓扑结构&#xff0c;金字塔型&#xff0c;最多是7层。usb 是主从结构&#xff0c;主和主或者从和从之间不能交换数据。理论上一个usb主控制器最多可接127个设备&#xff0c;协议规定每个usb设备具有一个7bit的地址&#xff0c;范围…

面试字节跳动后的2点总结,建议收藏!

首先我来辟个谣&#xff1a;随便打开一个招聘网站&#xff0c;你会发现前端工程师的岗位需求依旧庞大&#xff0c;大厂人才奇缺&#xff0c;就业薪资起点高&#xff0c;无行业限制。&#xff08;数据来源&#xff1a;职友集&#xff09;前端开发的行业大环境行业升级&#xff0…

phpexcel中文教程-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护

转载连接&#xff1a;http://www.cnblogs.com/huangcong/p/3687665.html phpexcel中文教程-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护 首先到phpexcel官网上下载最新的phpexcel类&#xff0c;下周解压缩一个cla…