- 判断浏览器是否支持响应式。
(function(w) {
"use strict";
w.matchMedia = w.matchMedia || function(doc, undefined ) {
var bool, docElem = doc.documentElement, refNode = docElem.firstElementChild || docElem.firstChild, fakeBody = doc.createElement("body" ), div = doc.createElement("div" );
div.id = "mq-test-1";
div.style.cssText = "position:absolute;top:-100em" ;
fakeBody.style.background = "none";
fakeBody.appendChild(div);
return function(q) {
//通过对元素加入media的样式,在判断元素是否因此而改变。
div.innerHTML = '­<style media="' + q + '"> #mq-test-1 { width: 42px; }</style>';
docElem.insertBefore(fakeBody, refNode);
bool = div.offsetWidth === 42;
docElem.removeChild(fakeBody);
return {
matches: bool,
media: q
};
};
}(w.document);
})(this);
- 收集所有css link 的 href。
ripCSS = function() {
//links在之前已经完成整理。 head = doc.getElementsByTagName( "head" )[0] || docElem;links = head.getElementsByTagName( "link" );
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]) {
if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
translate(sheet.styleSheet.rawCssText, href, media);
parsedSheets[href] = true;
} else {
if (!/^([a-zA-Z:]*\/\/)/ .test(href) && !base || href.replace(RegExp.$1, "").split("/" )[0] === w.location.host) {
if (href.substring(0, 2) === "//" ) {
href = w.location.protocol + href;
}
requestQueue.push({
href: href,
media: media
});
}
}
}
}
makeRequests();
};
- 整理相关 @media 媒体查询脚本的元数据。
translate = function(styles, href, media) {
//styles是.css文件的文本。通过ajax发起请求获取得到。
//对styles替换掉无效部分,匹配其中@media部分到变量qs。
//对styles替换掉无效部分,匹配其中@media部分到变量qs。
var qs = styles.replace( respond.regex.comments, "").replace(respond.regex.keyframes, "").match(respond.regex.media), ql = qs && qs.length || 0;
href = href.substring(0, href.lastIndexOf( "/"));
var repUrls = function(css) {
return css.replace( respond.regex.urls, "$1" + href + "$2$3");
}, useMedia = !ql && media;
if (href.length) {
href += "/";
}
if (useMedia) {
ql = 1;
}
//分析qs,得出mediastyles的各项参数。整理出下图的数据结构。
for ( var i = 0; i < ql; i++) {
var fullq, thisq, eachq, eql;
if (useMedia) {
fullq = media;
rules.push(repUrls(styles));
} else {
fullq = qs[i].match( respond.regex.findStyles) && 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];
if (isUnsupportedMediaQuery(thisq)) {
continue;
}
mediastyles.push({
media: thisq.split( "(")[0].match(respond.regex.only) && RegExp.$2 || "all",
rules: rules.length - 1,
hasquery: thisq.indexOf( "(") > -1,
minw: thisq.match( respond.regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || "" ),
maxw: thisq.match( respond.regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || "" )
});
}
}
applyMedia();
}
- 实现 @media 的相关功能。
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();
//之前已经定义resizeThrottle = 30;
//如果连续的resize在30ms内,延迟30ms后在触发一次resize job。
//如果连续的resize在30ms内,延迟30ms后在触发一次resize job。
//formResize表示经过Respond初始化resize后,手工改变屏幕大小。
if (fromResize && lastCall && now - lastCall < resizeThrottle) {
w.clearTimeout( resizeDefer);
resizeDefer = w.setTimeout( applyMedia, resizeThrottle);
return;
} else {
lastCall = now;
}
//整理出不含@media的各种设备对应的样式。
for (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";
if (!!min) {
min = parseFloat(min) * (min.indexOf(em) > -1 ? eminpx || getEmValue() : 1);
}
if (!!max) {
max = parseFloat(max) * (max.indexOf(em) > -1 ? eminpx || getEmValue() : 1);
}
//如果满足以下条件,将样式添加到该设备的样式集合styleBlocks中。
//1.如果不是媒体查询 !thisstyle.hasquery。
//2.如果存在媒体查询的min-width或者max-width配置。
//3.如果当前设备宽度在媒体查询的min-width、max-width之间。
//1.如果不是媒体查询 !thisstyle.hasquery。
//2.如果存在媒体查询的min-width或者max-width配置。
//3.如果当前设备宽度在媒体查询的min-width、max-width之间。
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]);
}
}
}
//初始appendedEls = [],head = doc.getElementsByTagName( "head" )[0] || docElem,是html head元素。。由于本方法是在window.setTimeout中执行,appendedEls作为全局变量,有记忆功能。用于删除<head>中的<link>,因为.css中的@media由Respond resize代替。
for ( var j in appendedEls) {
if (appendedEls.hasOwnProperty(j)) {
if (appendedEls[j] && appendedEls[j].parentNode === head) {
head.removeChild(appendedEls[j]);
}
}
}
appendedEls.length = 0;
//将同一设备的样式组合到一个<STYLE>中,插入到html <head>中,如下:
//http://www.w3school.com.cn/tags/att_style_media.asp
//所有主流浏览器都支持 media 属性的 screen、print以及all值。
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;
head.insertBefore(ss, lastLink.nextSibling);
if (ss.styleSheet) {
ss.styleSheet.cssText = css;
} else {
ss.appendChild(doc.createTextNode(css));
}
appendedEls.push(ss);
}
}
}
- 对于手工改变屏幕尺寸的响应。
ripCSS();
respond.update = ripCSS;
respond.getEmValue = getEmValue;
function callMedia() {
applyMedia(true);
}
//对屏幕尺寸的响应,调用callMedia方法,实质是调用applyMedia(true);
//IE8不支持addEventListener。
if (w.addEventListener) {
w.addEventListener( "resize", callMedia, false);
} else if (w.attachEvent) {
w.attachEvent("onresize", callMedia);
}
相关推荐
"respond.js"是一个小型的JavaScript文件,用于为不支持媒体查询的老旧IE浏览器提供响应式设计的支持。尽管现代浏览器普遍支持媒体查询,但考虑到兼容性问题,这个文件仍然是必要的。 "images"目录可能包含了项目中...
在没有respond.js的情况下,老版IE浏览器无法理解并应用媒体查询,这会导致响应式设计在这些浏览器上失效,用户将无法获得与现代浏览器相同的浏览体验。respond.js通过注入一些JavaScript代码,模拟了对媒体查询的...
总的来说,`respond.js`是解决IE8等老版本浏览器对响应式设计支持不足问题的有效工具。通过理解其工作原理和正确集成,我们可以确保在广泛的浏览器环境中提供一致的用户体验。对于开发者来说,熟悉`respond.js`及其...
在压缩包文件"GB-html5-respond-master"中,可能包含了一些关于如何结合HTML5和REM实现响应式布局的示例代码或教程,你可以进一步研究学习。 总的来说,通过JavaScript动态计算REM,我们可以更精确地控制移动端页面...
`respond.js`是一个轻量级的JavaScript库,由Jeffrey Way创建,它为不支持媒体查询的浏览器(如IE8)提供了后退支持,从而使得Bootstrap在这些浏览器上也能展现出响应式特性。 首先,我们需要理解响应式设计的概念...
响应式设计在现代网页开发中扮演着至关重要的角色,它使得网站能够在不同设备和屏幕尺寸上呈现出良好的用户体验。"respond.min.js"是Bootstrap框架中一个关键的JavaScript库,专门用于解决Internet Explorer 8(以及...
"Respond" 是一个这样的解决方案,它旨在简化响应式布局的实现,尤其针对那些不支持CSS媒体查询(Media Queries)的老式浏览器。在JavaScript领域,Respond作为一个轻量级的库,为开发者提供了在旧版IE浏览器中实现...
"respond.main.js"可能是一个用于处理响应式布局的JavaScript库,它可能利用了JIT编译来优化代码执行。 在JavaScript环境中,编译过程分为两个主要步骤:解析和执行。解析阶段,源代码被转化为抽象语法树(AST),...
`respond.min.js` 是一个响应式媒体查询的补丁,主要用于为不支持CSS3媒体查询的浏览器(如IE8)提供支持。在Bootstrap3中,响应式设计是核心功能之一,它使得网站能够自适应不同设备的屏幕尺寸,提供良好的用户体验...
响应式网页设计能够通过一套代码实现对多种屏幕尺寸的适应,提升了用户体验,也减少了为不同设备开发特定页面的工作量。CSS3中的@media规则就是用来实现响应式网页设计的关键技术之一。 首先,我们来看一下为什么...
在不支持媒体查询的IE浏览器中,Respond.js会解析CSS中的媒体查询规则,从而使这些浏览器也能实现响应式布局。"respond.min.js"就是这个库的压缩版本,应当在HTML文档的部分引入。 结合以上四个组件,你可以创建一...
基于RxJava 的函数式 Reactive 风格的 Java web 框架。示例代码:public static void main(String[] args) { // Note the Server class here is foundation.stack.datamill.http.Server Server ...
CSS代码部分是实现响应式效果的核心。`<nav>`元素设置了相对定位,这将在后续的菜单展开动画中起到关键作用。导航列表`<ul>`的`margin`和`padding`设置为零,`<li>`元素使用`display: inline-block`而不是`float:...
HTML5 和 CSS3 响应式设计标语和部分标题的 CSS3 过渡为高像素比屏幕交换图像用于创建 CSS 文件的 CSS 预处理器 (SCSS) 优化图像用于 IE8 的HTML5shiv.js 用于 IE8 的Respond.js 适用于 IE8,9 的CSS3 PIE Normalize...
4. **响应式视频框架**:如FitVids.js 或 Respond.js,这些框架可以帮助处理视频元素的自适应布局,使其能适应不同屏幕尺寸。 5. **媒体查询**:结合@media查询,针对不同设备和屏幕尺寸应用不同的视频样式,以确保...
2. ** respond.js **:Bootstrap使用媒体查询进行响应式设计,但IE8不支持媒体查询。可以通过引入respond.js库来模拟这一功能,使得IE8可以识别和应用媒体查询。 3. **html5shiv **:IE8及以下版本不识别HTML5的新...
2. `respond.min.js`: 这个文件是Scott Jehl创建的,用于在不支持CSS3媒体查询的IE6-8浏览器中提供响应式设计支持。响应式设计允许网页根据用户设备的屏幕尺寸和方向自动调整布局,而媒体查询是实现这一目标的关键...
压缩包中的"respond"文件可能包含了响应式设计所需的CSS框架或者库,如Respond.js。这个小型JavaScript库用于为不支持CSS3媒体查询的旧版本IE浏览器添加响应式功能。通过这样的库,可以确保即使在老旧的浏览器上,...
响应式设计在现代网页开发中占据着核心地位,特别是在创建导航栏时,因为它们需要适应各种屏幕尺寸。本文将深入探讨如何使用纯JavaScript(Vanilla JavaScript)和SCSS(Sass预处理器)来构建一个带有下拉菜单的响应...