Media Queries之Respond.js
一、stackoverflow上面对css3-mediaqueries.js与respond.js的比较
css3-mediaqueries.js
Pros
Supports min, max and min+max mediaqueries
Supports px and em values
Reacts on window resize
Elaborates on-page CSS (style tag) and external stylesheets
Cons
Doesn't support width mediaquery
Doesn't elaborate link[media="screen and ..."] nor @imported stylesheet
respond.js
Pros
Supports min, max and min+max mediaqueries
Supports px and em values
Reacts on window resize
Elaborates external stylesheets only
Cons
Doesn't support width mediaquery
Doesn't elaborate on-page CSS, link [media="screen and ..."] nor @imported stylesheets
It may cause a javascript error when combined with jQuery on load events, to solve it you need to place the script at the end of the page
二、Respond.js源码分析
https://github.com/scottjehl/Respond
A fast & lightweight polyfill for min/max-width CSS3 Media Queries (for IE 6-8, and more)
Respond.js应用的例子,参考http://skinnyties.com
查看skinnyties.com源代码,可以看到
可以在GitHub上可以下载它的未压缩版本respond.src.js(或者将min文件format,不推荐,因为JS压缩后的变量名都是处理过的,不方便阅读),本文使用Fiddler进行本地重定向,分析源码。
1.监听resize事件,以达到改变窗口大小实时响应
function callMedia(){applyMedia( true );
}
if( win.addEventListener ){// 标准2级DOM事件模型win.addEventListener( "resize", callMedia, false );
}
else if( win.attachEvent ){// IE事件模型(6、7、8)win.attachEvent( "onresize", callMedia );
}
2.提取CSS文件路径
var doc = win.document,docElem = doc.documentElement,mediastyles = [],rules = [],appendedEls = [],parsedSheets = {},resizeThrottle = 30,head = doc.getElementsByTagName( "head" )[0] || docElem,base = doc.getElementsByTagName( "base" )[0],links = head.getElementsByTagName( "link" ),requestQueue = [],// 遍历CSS路径ripCSS = function(){for( var i = 0; i < links.length; i++ ){var sheet = links[ i ],href = sheet.href,media = sheet.media,isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";if( !!href && isCSS && !parsedSheets[ href ] ){// selectivizr exposes css through the rawCssText expandoif (sheet.styleSheet && sheet.styleSheet.rawCssText) {translate( sheet.styleSheet.rawCssText, href, media );parsedSheets[ href ] = true;} else {// 判断条件:// 1.有形如http://这样的href需要判断http://后面的根目录是否等于location.host。// 2.不以形如http://这样开头的href,同时不包含<base>,// 所以它不支持带有<base>的相对hrefif( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) ||href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){requestQueue.push( {href: href,media: media} );}}}}makeRequests();}
3.发送ajax请求返回CSS内容
// 递归执行获得CSS文本
// 递归配合shift()可以保证最后被遍历的CSS具有最高的优先级
makeRequests = function(){if( requestQueue.length ){var thisRequest = requestQueue.shift();ajax( thisRequest.href, function( styles ){translate( styles, thisRequest.href, thisRequest.media );parsedSheets[ thisRequest.href ] = true;// 在递归函数外面包裹一层setTimeout,// 使得函数以异步的方式执行,防止栈溢出win.setTimeout(function(){ makeRequests(); },0);} );}
}
// ajax方法
ajax = function( url, callback ) {var req = xmlHttp();if (!req){return;} req.open( "GET", url, true );req.onreadystatechange = function () {if ( req.readyState !== 4 || req.status !== 200 && req.status !== 304 ){return;}callback( req.responseText );};if ( req.readyState === 4 ){return;}req.send( null );
}
4.取出CSS中具有形如 @media screen and (max-width: 480px) 的各个块
translate = function( styles, href, media ){// 匹配各个@media {...}var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ),ql = qs && qs.length || 0;//try to get CSS pathhref = href.substring( 0, href.lastIndexOf( "/" ) );var repUrls = function( css ){return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );},// useMedia=true表示<link>是否具有media属性并且// CSS样式中没有@media块useMedia = !ql && media;//if path exists, tack on trailing slashif( href.length ){ href += "/"; } if( useMedia ){ql = 1;}for( var i = 0; i < ql; i++ ){var fullq, thisq, eachq, eql;//media attrif( useMedia ){fullq = media;rules.push( repUrls( styles ) );}// rules保存了每个@media块内部的样式else{fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );}eachq = fullq.split( "," );eql = eachq.length;for( var j = 0; j < eql; j++ ){thisq = eachq[ j ];// 所有media块mediastyles.push( { media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all",// 对应media块在rules数组中的样式rules : rules.length - 1,hasquery : thisq.indexOf("(") > -1,minw : thisq.match( /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), maxw : thisq.match( /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )} );} }applyMedia();
}
5.将匹配的样式加入文档中
applyMedia = function( fromResize ){var name = "clientWidth",docElemProp = docElem[ name ],// 取得当前页面宽度currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,styleBlocks = {},lastLink = links[ links.length-1 ],now = (new Date()).getTime();// 函数节流,延迟调用if( fromResize && lastCall && now - lastCall < resizeThrottle ){win.clearTimeout( resizeDefer );resizeDefer = win.setTimeout( applyMedia, resizeThrottle );return;}else {lastCall = now;}// 遍历所有mediafor( var i in mediastyles ){if( mediastyles.hasOwnProperty( i ) ){var thisstyle = mediastyles[ i ],min = thisstyle.minw,max = thisstyle.maxw,minnull = min === null,maxnull = max === null,em = "em";// 支持以em为单位的宽度,定义了一个getEmValue方法计算em能换算成多少pxif( !!min ){min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );}if( !!max ){max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );}// 筛选宽度匹配的样式if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){if( !styleBlocks[ thisstyle.media ] ){styleBlocks[ thisstyle.media ] = [];}styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );}}}// 删除已存在的respond样式for( var j in appendedEls ){if( appendedEls.hasOwnProperty( j ) ){if( appendedEls[ j ] && appendedEls[ j ].parentNode === head ){head.removeChild( appendedEls[ j ] );}}}// 在文档中插入respond样式for( var k in styleBlocks ){if( styleBlocks.hasOwnProperty( k ) ){var ss = doc.createElement( "style" ),css = styleBlocks[ k ].join( "\n" );ss.type = "text/css"; ss.media = k;// originally, ss was appended to a documentFragment and sheets were appended in bulk.// this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set,// so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!head.insertBefore( ss, lastLink.nextSibling );if ( ss.styleSheet ){ // IE下ss.styleSheet.cssText = css;}else {ss.appendChild( doc.createTextNode( css ) );}//存储在appendedEls中,下次以便跟踪删除appendedEls.push( ss );}}
}
三、Respond.js带来的跨域请求问题
Respond.js通过ajax请求CSS文件,所以如果CSS文件存放在CDN上面(或者子域中),那么需要引入一个代理页面实现跨域连接。
GitHub地址
引入方法:
<!-- Respond.js proxy on external server -->
<link href="http://externalcdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" /><!-- Respond.js redirect location on local server -->
<link href="/path/to/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" /><!-- Respond.js proxy script on local server -->
<script src="/path/to/respond.proxy.js"></script>
转载于:https://www.cnblogs.com/zhaodongyu/p/3253584.html
Media Queries之Respond.js相关推荐
- 移动端zepot媒体查询media queries
使用zepot做轮播图 <head> <meta charset="utf-8"> <meta name="viewport" c ...
- 低版本浏览器支持css3 Media查询的方法, ie6-ie8 不支持css3 的时候用respond.js,html5shiv.js 【非常实用哦】。。。。。。。。。。。。...
Respond.js 是一个快速.轻量的 polyfill,用于为 IE6-8 以及其它不支持 CSS3 Media Queries 的浏览器提供媒体查询的 min-width 和 max-width ...
- Respond.js让IE6-8支持CSS3 Media Query
原文地址: http://caibaojian.com/respondjs.html 实现思路 1.把head中所有<link rel="sheetstyle" href=& ...
- 解决低版本IE关于html5新特性的兼容性问题html5shiv.js和Respond.js,以及excanvas.js解决低版本IE不支持canvas的问题...
插件:html5shiv.js 让IE9以下版本支持html5新标签,git地址https://github.com/aFarkas/html5shiv 用于解决IE9以下版本浏览器对HTML5新增标 ...
- css3的媒体查询(Media Queries)
css3的媒体查询(Media Queries) 我今天就总结一下响应式设计的核心CSS技术Media(媒体查询器)的用法. 先看一个简单的例子: <link rel="stylesh ...
- Respond JS有什么作用
Respond.js 是一个快速.轻量的 polyfill,用于为 IE6-8 以及其它不支持 CSS3 Media Queries 的浏览器提供媒体查询的 min-width 和 max-width ...
- html5加js兼容性辅助,解决低版本IE关于html5新特性的兼容性问题html5shiv.js和Respond.js,以及excanvas.js解决低版本IE不支持canvas的问题...
插件:html5shiv.js 让IE9以下版本支持html5新标签,git地址https://github.com/aFarkas/html5shiv 用于解决IE9以下版本浏览器对HTML5新增标 ...
- CSS3的媒体查询(Media Queries)与移动设备显示尺寸大全
文章目录 媒体查询介绍 Media Queries具体使用 一.最大宽度Max Width 二.最小宽度Min Width 三.多个Media Queries使用 四.设备屏幕的输出宽度Device ...
- CSS之Responsive设计和CSS3 Media Queries的结合
随着高科技的发展,现在我们浏览网页不在局限于PC机上了,用户可使用上网的设备是越来越多的品种:手机.小笔记本.iPad.Playbook,以及PC机,而且PC机的显展大小各不一致.这样一来不同的屏幕分 ...
最新文章
- python捕获异常后处理_python异常捕获处理
- 找出现实中符合这三种模式的互联网产品
- 【theano-windows】学习笔记九——softmax手写数字分类
- Oracle Class4. 数据库对象(同义词,序列,视图,索引,簇)
- 5G精华问答 | 大数据和5G有什么关系?
- 后台原理_电气控制原理动图22张,超赞!
- c++友元函数及运算符重载
- Linux——Ubuntu安装Fcitx以及Fcitx输入中文不显示候选词框的解决办法
- (八)Locust 设置断言
- progressDialog 为什么设置了setProgress()方法无反应?
- [C入门 - 游戏编程系列] 贪吃蛇篇(一) - 世界定义
- 聊聊拒绝忽悠的批判性思维
- Objective-C 入门篇
- cp -r命令 linux什么意思,linux系统里cp指的是什么意思
- 九阳神功足疗是什么?分析美团按摩项目,泡脚足浴排第一
- 美颜特效、黑白照片上色、AI人像动漫化,达摩院的学习营来了!
- 浅谈统一权限管理平台
- 阿拉伯数字转韩文、中文
- cad计算机中怎么用除号,CAD中特殊符号如何输入?超全教程,一看就懂!
- 敏捷测试 之 借力DSL