移动端前端适配方案

关于移动适配技术方案4种对比:

  1. 媒体查询的方式即CSS3的meida queries
  2. flex 弹性布局 (天猫首页)
  3. rem+viewport缩放 (淘宝首页)
  4. rem 方式 (魅族移动端的实现方式)

Media Queries

meida queries 的方式可以说是我早期采用的布局方式,它主要是通过查询设备的宽度来执行不同的 css 代码,最终达到界面的配置。核心语法是:

1
2
3
@media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的CSS样式*/
/*你的css代码*/
}

优点

  • media query可以做到设备像素比的判断,方法简单,成本低,特别是对移动和PC维护同一套代码的时候。目前像- Bootstrap等框架使用这种方式布局
  • 图片便于修改,只需修改css文件
  • 调整屏幕宽度的时候不用刷新页面即可响应式展示

缺点

  • 代码量比较大,维护不方便
  • 为了兼顾大屏幕或高清设备,会造成其他设备资源浪费,特别是加载图片资源
  • 为了兼顾移动端和PC端各自响应式的展示效果,难免会损失各自特有的交互方式

flex弹性布局

它的viewport是固定的:
高度定死,宽度自适应,元素都采用px做单位。

rem+viewport 缩放

根据屏幕宽度设定 rem 值,需要适配的元素都使用 rem 为单位,不需要适配的元素还是使用 px 为单位。
根据rem将页面放大dpr倍, 然后viewport设置为1/dpr.

  • 如iphone6 plus的dpr为3, 则页面整体放大3倍, 1px(css单位)在plus下默认为3px(物理像素)
  • 然后viewport设置为1/3, 这样页面整体缩回原始大小. 从而实现高清。

设备的物理分辨率/(devicePixelRatio * scale)
在scale为1的情况下,device-width = 设备的物理分辨率/devicePixelRatio 。

rem 实现

viewport也是固定的:
通过以下代码来控制rem基准值(设计稿以720px宽度量取实际尺寸)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
!function (d) {
var c = d.document;
var a = c.documentElement;
var b = d.devicePixelRatio;
var f;

function e() {
var h = a.getBoundingClientRect().width, g;
if (b === 1) {
h = 720
}
if(h>720) h = 720;//设置基准值的极限值
g = h / 7.2;
a.style.fontSize = g + "px"
}

if (b > 2) {
b = 3
} else {
if (b > 1) {
b = 2
} else {
b = 1
}
}
a.setAttribute("data-dpr", b);
d.addEventListener("resize", function () {
clearTimeout(f);
f = setTimeout(e, 200)
}, false);
e()
}(window);

css通过sass预编译,设置量取的px值转化rem的变量$px: (1/100)+rem;;

淘宝实现方式

transform: scale(0.5)

CSS代码:

1
2
3
4
5
6
7
8
div{
width: 1px;
height: 100%;
display: block;
border-left: 1px solid #e5e5e5;
-webkit-transform: scaleX(.5);
transform: scaleX(.5);
}

缺点:

  • 圆角无法实现,实现4条边框比较麻烦,并且只能单独实现,如果嵌套,会对包含的效果产生不想要的效果,所以此方案配合:after和before独立使用较多。
    box-shadow

实现方法:

利用CSS对阴影处理的方式实现0.5px的效果。

1
-webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);

优点:

基本所有场景都能满足,包含圆角的button,单条,多条线。

缺点:

  • 颜色不好处理, 黑色 rgba(0,0,0,1) 最深的情况了。有阴影出现,不好用。
  • 大量使用box-shadow可能会导致性能瓶颈。
  • 四条边框实现效果不理想。

图片实现

使用 background-image 实现1px有两种方式: 渐变 linear-gradient 或直接使用图片(base64)。

渐变 linear-gradient (50%有颜色,50%透明)

单条线:

1
2
3
4
5
6
7
div {
height: 1px;
background-image: -webkit-linear-gradient(top,transparent 50%,#000 50%);
background-position: top left;
background-repeat: no-repeat
background-size: 100% 1px;
}

多条线:

1
2
3
4
5
6
div {
background-image:-webkit-linear-gradient(top, transparent 50%, #000 50%),-webkit-linear-gradient(bottom, transparent 50%, #000 50%),-webkit-linear-gradient(left, transparent 50%, #000 50%),-webkit-linear-gradient(right, transparent 50%, #000 50%);
background-size: 100% 1px,100% 1px,1px 100%,1px 100%;
background-repeat: no-repeat;
background-position: top left, bottom left, left top, right top;
}

优点:

  • 可以设置单条,多条边框
  • 可以设置颜色

    缺点:

  • 大量使用渐变可能导致性能瓶颈

  • 代码量大
  • 多背景图片有兼容性问题
分享到

web前端自适应技巧相关学习

meta基础知识

H5页面窗口自动调整到设备宽度,并禁止用户缩放页面

1
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />

忽略将页面中的数字识别为电话号码

1
<meta name="format-detection" content="telephone=no" />

忽略Android平台中对邮箱地址的识别

1
<meta name="format-detection" content="email=no" />

当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari

1
2
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- ios7.0版本以后,safari上已看不到效果 -->

将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式

1
2
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- 可选default、black、black-translucent -->

viewport模板

viewport模板——通用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>标题</title>
<link rel="stylesheet" href="index.css">
</head>

<body>
这里开始内容
</body>

</html>

viewport模板 - target-densitydpi=device-dpi,android 2.3.5以下版本不支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=750, user-scalable=no, target-densitydpi=device-dpi">
<!-- width取值与页面定义的宽度一致 -->
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>标题</title>
<link rel="stylesheet" href="index.css">
</head>

<body>
这里开始内容
</body>

</html>

移动端如何定义字体font-family

中文字体使用系统默认即可,英文用Helvetica

1
2
/* 移动端定义字体的代码 */
body{font-family:Helvetica;}

移动端字体单位font-size选择px还是rem

对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可

对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备

rem配置参考,适合视觉稿宽度为640px的:

1
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">

1
2
3
4
5
6
7
8
html{font-size:10px}
@media screen and (min-width:321px) and (max-width:375px){html{font-size:11px}}
@media screen and (min-width:376px) and (max-width:414px){html{font-size:12px}}
@media screen and (min-width:415px) and (max-width:639px){html{font-size:15px}}
@media screen and (min-width:640px) and (max-width:719px){html{font-size:20px}}
@media screen and (min-width:720px) and (max-width:749px){html{font-size:22.5px}}
@media screen and (min-width:750px) and (max-width:799px){html{font-size:23.5px}}
@media screen and (min-width:800px){html{font-size:25px}}

移动端click屏幕产生200-300 ms的延迟响应

触摸事件的响应顺序

1、ontouchstart
2、ontouchmove
3、ontouchend
4、onclick

什么是Retina 显示屏,带来了什么问题

retina:一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由1个变为多个,如在同样带下的屏幕上,苹果设备的retina显示屏中,像素点1个变为4个

在高清显示屏中的位图被放大,图片会变得模糊,因此移动端的视觉稿通常会设计为传统PC的2倍

那么,前端的应对方案是:
设计稿切出来的图片长宽保证为偶数,并使用backgroud-size把图片缩小为原来的1/2

1
2
//例如图片宽高为:200px*200px,那么写法如下
.css{width:100px;height:100px;background-size:100px 100px;}

其它元素的取值为原来的1/2,例如视觉稿40px的字体,使用样式的写法为20px

1
.css{font-size:20px}

ios系统中元素被触摸时产生的半透明灰色遮罩怎么去掉

1
a,button,input,textarea{-webkit-tap-highlight-color: rgba(0,0,0,0;)}

部分android系统中元素被点击时产生的边框怎么去掉

1
2
3
4
a,button,input,textarea{
-webkit-tap-highlight-color: rgba(0,0,0,0;)
-webkit-user-modify:read-write-plaintext-only;
}

webkit表单元素的默认外观怎么重置

1
.css{-webkit-appearance:none;}

禁止ios和android用户选中文字

1
.css{-webkit-user-select:none}

禁止ios 长按时不触发系统的菜单,禁止ios&android长按时下载图片

1
.css{-webkit-touch-callout: none}

IE10(winphone8)表单元素默认外观如何重置

禁用 radio 和 checkbox 默认样式

::-ms-check 适用于表单复选框或单选按钮默认图标的修改,同样有多个属性值,设置它隐藏 (display:none) 并使用背景图片来修饰可得到我们想要的效果。

1
2
3
input[type=radio]::-ms-check,input[type=checkbox]::-ms-check{
display: none;
}

禁用PC端表单输入框默认清除按钮

当表单文本输入框输入内容后会显示文本清除按钮,::-ms-clear 适用于该清除按钮的修改,同样设置使它隐藏 (display:none) 并使用背景图片来修饰可得到我们想要的效果。

1
2
3
input[type=text]::-ms-clear,input[type=tel]::-ms-clear,input[type=number]::-ms-clear{
display: none;
}

禁用 select 默认下拉箭头

::-ms-expand 适用于表单选择控件下拉箭头的修改,有多个属性值,设置它隐藏 (display:none) 并使用背景图片来修饰可得到我们想要的效果。

1
2
3
select::-ms-expand {
display: none;
}

打电话发短信写邮件怎么实现

打电话,发短信(winphone系统无效),写邮件

1
2
3
<a href="tel:0755-10086">打电话给:0755-10086</a>
<a href="sms:10086">发短信给: 10086</a>
<a href="mailto:peun@foxmail.com">peun@foxmail.com</a>

屏幕旋转的事件和样式

事件

window.orientation,取值:正负90表示横屏模式、0和180表现为竖屏模式;

1
2
3
4
5
6
7
8
9
10
11
window.onorientationchange = function(){
switch(window.orientation){
case -90:
case 90:
alert("横屏:" + window.orientation);
case 0:
case 180:
alert("竖屏:" + window.orientation);
break;
}
}

样式

1
2
3
4
5
6
7
8
9
//竖屏时使用的样式
@media all and (orientation:portrait) {
.css{}
}

//横屏时使用的样式
@media all and (orientation:landscape) {
.css{}
}

audio元素和video元素在ios和andriod中无法自动播放

应对方案:触屏即播

1
2
3
$('html').one('touchstart',function(){
audio.play()
})

手机拍照和上传图片

的accept 属性

1
2
3
4
<!-- 选择照片 -->
<input type=file accept="image/*">
<!-- 选择视频 -->
<input type=file accept="video/*">

使用总结:

ios 有拍照、录像、选取本地图片功能
部分android只有选取本地图片功能
winphone不支持
input控件默认外观丑陋

微信浏览器用户调整字体大小后页面矬了,怎么阻止用户调整

原因

android侧是复写了layoutinflater 对textview做了统一处理
ios侧是修改了body.style.webkitTextSizeAdjust值
解决方案:

android使用以下代码,该接口只在微信浏览器下有效(感谢jationhuang同学提供)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 页面加入这段代码可使Android机器页面不再受到用户字体缩放强制改变大小
* 但是会有一个1秒左右的延迟,期间可以考虑通过loading展示
* 仅供参考
*/
(function(){
if (typeof(WeixinJSBridge) == "undefined") {
document.addEventListener("WeixinJSBridgeReady", function (e) {
setTimeout(function(){
WeixinJSBridge.invoke('setFontSizeCallback',{"fontSize":0}, function(res) {
alert(JSON.stringify(res));
});
},0);
});
} else {
setTimeout(function(){
WeixinJSBridge.invoke('setFontSizeCallback',{"fontSize":0}, function(res) {
alert(JSON.stringify(res));
});
},0);
}
})();

ios使用-webkit-text-size-adjust禁止调整字体大小
body{-webkit-text-size-adjust: 100%!important;}
最好的解决方案:

整个页面用rem或者百分比布局

消除transition闪屏

网络都是这么写的,但我并没有测试出来

1
2
3
4
5
6
.css{
/*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/
-webkit-transform-style: preserve-3d;
/*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/
-webkit-backface-visibility: hidden;
}

开启硬件加速

解决页面闪白
保证动画流畅

1
2
3
4
5
6
.css {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}

input在ios下,输入的时候英文首字母的默认大写

1
<input autocapitalize="off" autocorrect="off" />

android 上去掉语音输入按钮

1
input::-webkit-input-speech-button {display: none}

移动端使用框架

  1. zepto.js
  2. iscroll.js
    解决页面不支持弹性滚动,不支持fixed引起的问题~
    实现下拉刷新,滑屏,缩放等功能~
  3. underscore.js

滑屏框架 slip.js iSlider.js fullpage.js
swiper.js

  1. flex布局
    flex布局目前可使用在移动中,并非所有的语法都全兼容,但以下写法笔者实践过,效果良好~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* ============================================================
flex:定义布局为盒模型
flex-v:盒模型垂直布局
flex-1:子元素占据剩余的空间
flex-align-center:子元素垂直居中
flex-pack-center:子元素水平居中
flex-pack-justify:子元素两端对齐
兼容性:ios 4+、android 2.3+、winphone8+
============================================================ */
.flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}
.flex-v{-webkit-box-orient:vertical;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}
.flex-1{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;}
.flex-align-center{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;}
.flex-pack-center{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}
.flex-pack-justify{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}

实例: 两端对齐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<style type="text/css">
/* ============================================================
flex:定义布局为盒模型
flex-v:盒模型垂直布局
flex-1:子元素占据剩余的空间
flex-align-center:子元素垂直居中
flex-pack-center:子元素水平居中
flex-pack-justify:子元素两端对齐
兼容性:ios 4+、android 2.3+、winphone8+
============================================================ */
.flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}
.flex-v{-webkit-box-orient:vertical;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}
.flex-1{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;}
.flex-align-center{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;}
.flex-pack-center{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}
.flex-pack-justify{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}
</style>
</head>
<body>

<div class="flex flex-pack-justify">
<div>模块一</div>
<div>模块二</div>
<div>模块三</div>
<div>模块四</div>
</div>

</body>
</html>

  1. FastClick

消除在移动浏览器上触发click事件与一个物理Tap(敲击)之间的300延迟

  1. Sea.js

提供简单、极致的模块化开发体验

分享到

viewpor网页自适应

viewport 手机端浏览器可视窗口大小

实际浏览器可视域的大小比默认viewport 宽度小 ,就会出现滚动条

1px 在不同设备上有不同定义

计算器显示器是通过显示像素点,显示图片的,像素越多看的细,像素越少越模糊,这个就是物理像素.
在css 中也有px属性,叫做设备独立像素
devicePixelRatio = 物理像素 / 独立像素。

viewport三大理论 ppk

  1. layout viewport layout viewport的宽度可以通过document.documentElement.clientWidth 来获取
  2. visual viewport visual viewport的宽度可以通过window.innerWidth 来获取
  3. ideal viewport 没有一个固定的尺寸,不同的设备拥有有不同的ideal viewport。

利用meta标签使用viewport

移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,我们需要的是ideal viewport。
那么怎么才能得到ideal viewport呢?这就该轮到meta标签出场了。

1
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1,user-scalable=no">

width 设置layout viewport 的宽度,为一个正整数,或字符串”device-width”
initial-scale 设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
height 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable 是否允许用户进行缩放,值为”no”或”yes”, no 代表不允许,yes代表允许

把当前的viewport宽度设置为 ideal viewport 的宽度

1
<meta name="viewport" content="width=device-width">  or <meta name="viewport" content="initial-scale=1">

淘宝的布局方案解析

(1)动态设置viewport的scale

1
2
var scale = 1 / devicePixelRatio;  
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

淘宝布局的第二个要点,就是html元素的font-size的计算公式,font-size = deviceWidth / 10:
(2)动态设置html的font-size

1
2
3
4
5
6
7
//flexible中定义<html>font-size
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';

(3)布局的时候,各元素的css尺寸=设计稿标注尺寸/设计稿横向分辨率/10
(4)font-size可能需要额外的媒介查询,并且font-size不使用rem

淘宝移动端自适应方案—lib.flexible库解析

它的主要js文件有三个,包括flexiblecss.js、flexible.js、makegrid.js
flexible.js—布局的核心js
flexiblecss.js—注入统一的css样式,比如去掉所有元素的内外边距,去掉默认边框等等
makegrid.js—栅格系统

阿里CDN:

其中initial-dpr会把dpr强制设置为给定的值。如果手动设置了dpr之后,不管设备是多少的dpr,都会强制认为其dpr是你设置的值。在此不建议手动强制设置dpr,因为在Flexible中,只对iOS设备进行dpr的判断,对于Android系列,始终认为其dpr为1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if (!dpr && !scale) {  
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}

flexible的实质 能通过js动态更改meta标签

1
2
3
4
5
6
7
8
9
10
11
var metaEl = doc.createElement('meta');  
var scale = isRetina ? 0.5:1;
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
document.documentElement.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
documen.write(wrap.innerHTML);
}
  • 动态改写标签
  • 给元素添加data-dpr属性,并且动态改写data-dpr的值
  • 给元素添加font-size属性,并且动态改写font-size的值

把视觉稿中的px转换成rem

目前Flexible会将视觉稿分成100份,而每一份被称为一个单位a。同时1rem单位被认定为10a。
1a = 7.5px
1rem = 75px
那么我们的视觉稿就分成了10a,也就是整个宽度为10rem,对应的font-size为75px;

推荐CSSREM——px转化rem小工具

使用[data-dpr]属性来区分不同dpr下的文本字号大小。

1
2
3
4
5
6
7
8
9
10
11
div {  
width: 1rem;
height: 0.4rem;
font-size: 12px; // 默认写上dpr为1的fontSize
}
[data-dpr="2"] div {
font-size: 24px;
}
[data-dpr="3"] div {
font-size: 36px;
}

字体慎用rem,误差太大了,因为不能满足任何屏幕下字体大小相同,所以建议标题类用rem,要求字体大小相同的部分还是用px

栅格系统—makegrid.js

js 代码

1
2
3
4
5
6
7
8
9
10
var gridMode = {  
'750-12':{ designWidth:750,designUnit:6,columnCount:12,columnXUnit:7,gutterXUnit:3,edgeXUnit:4
},
'750-6': { designWidth:750,designUnit:6,columnCount:6,columnXUnit:17,gutterXUnit:3,edgeXUnit:4
},
'640-12': { designWidth:640,designUnit:4,columnCount:12,columnXUnit:11,gutterXUnit:2,edgeXUnit:3
},
'640-6': { designWidth:640,designUnit:4,columnCount:6,columnXUnit:24,gutterXUnit:2,edgeXUnit:3
}
}

参数说明
lib.flexible.makeGrid(params)
• [Object params]

  • designWidth - 设计稿宽度

  • designUnit - 设计稿最小单位a(以px为单位)

  • columnCount - 栅格列数
  • columnXUnit - 栅格列宽(以a为单位)
  • gutterXUnit - 栅格间距(以a为单位)

  • edgeXUnit - 页面左右边距(以a为单位)

  • className - 栅格样式的名称(可省略,默认为grid)

利用meta输出栅格样式


栅格化代码举例

1
2
3
4
5
6
<meta content="modeName=640-12" name="grid" />  
<div class="grid">
<div class="col-4"></div>
<div class="col-4"></div>
<div class="col-4"></div>
</div>

瞅瞅flexible.js 源码

flexible.js—布局的核心js,里边主要包含下边几点来实现适配布局

1)设置像素比dpr和scale
有两种模式:一种是自适应,一种是手动配置dpr
适应模式:根据已有的meta标签来设置dpr和scale
手动配置:
2)如果没有设置缩放比,根据苹果用户或者安卓用户设置缩放比。iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案,安卓的均采用1。
源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var isAndroid = win.navigator.appVersion.match(/android/gi);  
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}

3)前边谈到淘宝布局方案的时候,说到淘宝触屏版布局的前提就是viewport的scale根据devicePixelRatio动态设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//为html标签添加data-dpr属性
docEl.setAttribute('data-dpr', dpr);
//如果没有meta[name="viewport",添加meta标签
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}

4)为html标签添加data-dpr属性
document.documentElement.setAttribute(‘data-dpr’, dpr);
5)刷新页面的rem基准值 (API—lib.flexible.refreshRem())

1
2
3
4
5
6
7
8
9
10
11
12
//根据dpr和物理像素设置rem
function refreshRem(){
//getBoundingClientRect().width相当于物理像素
var width = docEl.getBoundingClientRect().width;
// width / dpr > 540等于独立像素
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}

6)什么时候执行refreshRem()呢?
第一种当窗口大小发生变化,也就是触发resize事件的时候;

1
2
3
4
win.addEventListener('resize', function() {  
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}, false);

第二种是当重新载入页面时,判断是否是缓存,如果是缓存,执行refreshRem()

1
2
3
4
5
6
win.addEventListener('pageshow', function(e) {  
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);

7)rem转化px (API—lib.flexible.rem2px([Number|String digital]))

1
2
3
4
5
6
7
8
flexible.rem2px = function(d) {  
//已定义var rem = width / 10;
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}

rem转化px计算公式=d*(width/10)
8)px转化rem (API—lib.flexible.px2rem([Number|String digital]))

1
2
3
4
5
6
7
flexible.px2rem = function(d) {  
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
}

px转化rem计算公式=d/(width/10)

css布局适配问题避免:

  1. 盒子,图片等宽度设置首选百分比,次而选择rem,高度可以是固定值
  2. 字体可以不用rem,误差太大了,且不能满足任何屏幕下字体大小相同,所以建议标题类用rem,要求字体大小相同的部分还是用px;
  3. 遇到内容排列显示的布局,建议放弃float,可以直接使用display:inline-block。
  4. 慎用position属性;absolute会脱离文档流,relative则不会
  5. 如何解决盒子边框溢出?当你把元素宽度设为 width:100%时,有时可能会遇到元素的宽度超出了屏幕,
    这时可对元素加box-sizing:border-box属性,用来指定盒子大小包含边框和内边距
  6. 去除button在ios上的默认样式
    -webkit-appearance: none; border-radius: 0;
  7. 不想让按钮touch时有蓝色的边框
    outline:none;
  8. 去除webkit的滚动条
    element::-webkit-scrollbar{

    display: none;
    }

  9. 遇到过一个问题就是,当手机端点击input弹出键盘,整个视窗的高度就会变为减去键盘的高度,
    页面底部样式会乱,当时解决方法是用js获取整个页面高度赋值给body,等于说在不同的设备下写死不同的body高度值,底部就不会乱了
    $(“body”).css(“height”,parseInt($(“.wrap”).height())+parseInt($(“.icon-main”).height()));
  10. 如果想改变 placeholder里的文字,需要用c伪类
    ::-webkit-input-placeholder{

    color:#ccc
    }

附上简单淘宝适配源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="modeName=640-12" name="grid" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
<meta name="keywords" content="">
<title></title>
<style>
</style>
</head>
<body>
<style>
.grid{
margin-top: 1rem ;
background-color: #ccc;
padding-top: 0.6rem;
}
.grid > div {
text-align: center;
font-size:0.4rem;
}
.pic{
width:2rem;
height:2rem;
margin-bottom: 0.4rem;
}
.pic img{
width:1.4rem;
height:1.4rem;
}
.pic p{
width:2rem;
height:0.6rem;
position:relative;
top:2px;
color:#666;
}
</style>
<div class="grid">
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
</div>
</body>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.2/flexible_css.js"></script>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.2/flexible.js"></script>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.2/makegrid.js"></script>
</html>
分享到

前端apicloud知识大纲笔记

app前端布局

  1. window
  2. frame
  3. fremegroup

布局方式

  1. 头部+内容
  2. 头部
  3. 侧拉导航

布局元素

  1. html
  2. css
  3. api模块

数据的交换

  1. file
  2. db <==sqlite
  3. localStorage
  4. perference :setPrets ,getPrets,removePrets
  5. 云端一体 数据存储
  6. api.ajax 服务器数据上传

    cookie session 无法在app中使用

网易新闻代码实现方法

使用的函数

  1. api.openWin();
  2. api.openFrame();
  3. api.setRefreshHeaderInfo() api.refreshHeaderLoadDone()

云端数据库使用

平台事件类型

  1. 设备
    电池电量:batterylow、batterystatus
    物理按键:keyback、keymenu
    音量按键:volumeup、volumedown
  2. 网络
    网络状态:online、offline
    云服务状态:smartupdatefinish
  3. 交互
    手势:swipeup、swipedown、swipeleft、swiperight
    滚动:scrolltobottom
    点击:tap
    长按:longpress
    状态栏:noticeclicked
    启动页:launchviewclicked
  4. 窗口
    窗口显示:viewappear
    窗口隐藏:viewdisappear
  5. 应用
    回到前台:resume
    进入后台:pause
    被其他应用调用:appindent
  6. 事件监听机制
    添加监听:api.addEventListener()
    删除监听:api.removeEventListener()
    发送事件:api.sentEvent()

    APP与数据云API通信

  7. 接口签名验证
    appId appKey 算法
  8. 3种调用方式
    1. 标准 ajax 或 api.ajax
    2. APICloud mcm 模块:user,file,model,query等
    3. APICloud mcm JS框架:
      开源分支
      APICloud-rest.js
      SHA1.js
      

      常用对话框窗口使用

  9. 提示对话框
    api.alert()
    api.confirm()
    api.prompt()
    api.toast()
  10. 状态对话框
    api.showProgress()
    api.hideProgress()
  11. 选择对话框
    api.actionSheet()
    api.datePicker()
分享到
Visitor

Intent

Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Solution Overview

  • A client that uses the Visitor pattern must create a ConcreteVisitor object and then traverse the object structure, visiting each element with the visitor.
  • When an element is visited, it calls the Visitor operation that corresponds to its class. The element supplies itself as an argument to this operation to let the visitor access its state, if necessary.

Participants

  • Visitor (NodeVisitor)
    • declares a Visit operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. That lets the visitor determine the concrete class of the element being visited. Then the visitor can access the element directly through its particular interface.

  • ConcreteVisitor (TypeCheckingVisitor)
    • implements each operation declared by Visitor. Each operation implements a fragment of the algorithm defined for the corresponding class of object in the structure. ConcreteVisitor provides the context for the algorithm and stores its local state. This state often accumulates results during the traversal of the structure.

  • Element (Node)
    • defines an Accept operation that takes a visitor as an argument.

  • ConcreteElement (AssignmentNode,VariableRefNode)
    • implements an Accept operation that takes a visitor as an argument.

  • ObjectStructure (Program)
    • can enumerate its elements.
    • may provide a high-level interface to allow the visitor to visit its elements.
    • may either be a composite or a collection such as a list or a set.

Classification

The Visitor design pattern is not known by another name.

分享到

flex布局

一、骰子的布局

骰子的一面,最多可以放置9个点。

codepen下面,就来看看Flex如何实现,从1个点到9个点的布局。你可以到查看Demo。

如果不加说明,本节的HTML模板一律如下。

1
2
3
<div class="box">
<span class="item"></span>
</div>

上面代码中,div元素(代表骰子的一个面)是Flex容器,span元素(代表一个点)是Flex项目。如果有多个项目,就要添加多个span元素,以此类推。

1.1 单项目

首先,只有左上角1个点的情况。Flex布局默认就是首行左对齐,所以一行代码就够了。

1
.box {display: flex;}

设置项目的对齐方式,就能实现居中对齐和右对齐。

1
2
3
4
.box {
display: flex;

}


1
2
3
4
.box {
display: flex;
justify-content: flex-end;
}

设置交叉轴对齐方式,可以垂直移动主轴。

1
2
3
4
.box {
display: flex;
align-items: center;
}

1
2
3
4
5
.box {
display: flex;
justify-content: center;
align-items: center;
}

1
2
3
4
5
.box {
display: flex;
justify-content: center;
align-items: flex-end;
}

1
2
3
4
5
.box {
display: flex;
justify-content: flex-end;
align-items: flex-end;
}

1.2 双项目


1
2
3
4
.box {
display: flex;
justify-content: space-between;
}


1
2
3
4
5
.box {
display: flex;
flex-direction: column;
justify-content: space-between;
}

1
2
3
4
5
6
.box {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}


1
2
3
4
5
6
.box {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
}


1
2
3
4
5
6
7
.box {
display: flex;
}

.item:nth-child(2) {
align-self: center;
}


1
2
3
4
5
6
7
8
.box {
display: flex;
justify-content: space-between;
}

.item:nth-child(2) {
align-self: flex-end;
}

1.3 三项目

1
2
3
4
5
6
7
8
9
10
11
.box {
display: flex;
}

.item:nth-child(2) {
align-self: center;
}

.item:nth-child(3) {
align-self: flex-end;
}

1.4 四项目

1
2
3
4
5
6
.box {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
align-content: space-between;
}

HTML代码如下。

1
2
3
4
5
6
7
8
9
10
<div class="box">
<div class="column">
<span class="item"></span>
<span class="item"></span>
</div>
<div class="column">
<span class="item"></span>
<span class="item"></span>
</div>
</div>

CSS代码如下。

1
2
3
4
5
6
7
8
9
10
11
.box {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}

.column {
flex-basis: 100%;
display: flex;
justify-content: space-between;
}

1.5 六项目


1
2
3
4
5
6

.box {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}

1
2
3
4
5
6
.box {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: space-between;
}

HTML代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="box">
<div class="row">
<span class="item"></span>
<span class="item"></span>
<span class="item"></span>
</div>
<div class="row">
<span class="item"></span>
</div>
<div class="row">
<span class="item"></span>
<span class="item"></span>
</div>
</div>

CSS代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.box {
display: flex;
flex-wrap: wrap;
}

.row{
flex-basis: 100%;
display:flex;
}

.row:nth-child(2){
justify-content: center;
}

.row:nth-child(3){
justify-content: space-between;
}

1.6 九项目

1
2
3
4
.box {
display: flex;
flex-wrap: wrap;
}

二、网格布局

2.1 基本网格布局

最简单的网格布局,就是平均分布。在容器里面平均分配空间,跟上面的骰子布局很像,但是需要设置项目的自动缩放。

HTML代码如下。

1
2
3
4
5
<div class="Grid">
<div class="Grid-cell">...</div>
<div class="Grid-cell">...</div>
<div class="Grid-cell">...</div>
</div>

CSS代码如下。

1
2
3
4
5
6
7
.Grid {
display: flex;
}

.Grid-cell {
flex: 1;
}

2.2 百分比布局

某个网格的宽度为固定的百分比,其余网格平均分配剩余的空间。

HTML代码如下。

1
2
3
4
5
<div class="Grid">
<div class="Grid-cell u-1of4">...</div>
<div class="Grid-cell">...</div>
<div class="Grid-cell u-1of3">...</div>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.Grid {
display: flex;
}

.Grid-cell {
flex: 1;
}

.Grid-cell.u-full {
flex: 0 0 100%;
}

.Grid-cell.u-1of2 {
flex: 0 0 50%;
}

.Grid-cell.u-1of3 {
flex: 0 0 33.3333%;
}

.Grid-cell.u-1of4 {
flex: 0 0 25%;
}

三、圣杯布局

圣杯布局(Holy Grail Layout)指的是一种最常见的网站布局。页面从上到下,分成三个部分:头部(header),躯干(body),尾部(footer)。其中躯干又水平分成三栏,从左到右为:导航、主栏、副栏。

HTML代码如下。

1
2
3
4
5
6
7
8
9
<body class="HolyGrail">
<header>...</header>
<div class="HolyGrail-body">
<main class="HolyGrail-content">...</main>
<nav class="HolyGrail-nav">...</nav>
<aside class="HolyGrail-ads">...</aside>
</div>
<footer>...</footer>
</body>

CSS代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.HolyGrail {
display: flex;
min-height: 100vh;
flex-direction: column;
}

header,
footer {
flex: 1;
}

.HolyGrail-body {
display: flex;
flex: 1;
}

.HolyGrail-content {
flex: 1;
}

.HolyGrail-nav, .HolyGrail-ads {
/* 两个边栏的宽度设为12em */
flex: 0 0 12em;
}

.HolyGrail-nav {
/* 导航放到最左边 */
order: -1;
}

如果是小屏幕,躯干的三栏自动变为垂直叠加。

1
2
3
4
5
6
7
8
9
10
11
@media (max-width: 768px) {
.HolyGrail-body {
flex-direction: column;
flex: 1;
}
.HolyGrail-nav,
.HolyGrail-ads,
.HolyGrail-content {
flex: auto;
}
}

四、输入框的布局
我们常常需要在输入框的前方添加提示,后方添加按钮。

HTML代码如下。

1
2
3
4
5
<div class="InputAddOn">
<span class="InputAddOn-item">...</span>
<input class="InputAddOn-field">
<button class="InputAddOn-item">...</button>
</div>

CSS代码如下。

1
2
3
4
5
6
7
.InputAddOn {
display: flex;
}

.InputAddOn-field {
flex: 1;
}

五、悬挂式布局

有时,主栏的左侧或右侧,需要添加一个图片栏。

HTML代码如下。

1
2
3
4
<div class="Media">
<img class="Media-figure" src="" alt="">
<p class="Media-body">...</p>
</div>

CSS代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
.Media {
display: flex;
align-items: flex-start;
}

.Media-figure {
margin-right: 1em;
}

.Media-body {
flex: 1;
}

六、固定的底栏

有时,页面内容太少,无法占满一屏的高度,底栏就会抬高到页面的中间。这时可以采用Flex布局,让底栏总是出现在页面的底部。

HTML代码如下。

1
2
3
4
5
<body class="Site">
<header>...</header>
<main class="Site-content">...</main>
<footer>...</footer>
</body>

CSS代码如下。

1
2
3
4
5
6
7
8
9
.Site {
display: flex;
min-height: 100vh;
flex-direction: column;
}

.Site-content {
flex: 1;
}

七,流式布局

每行的项目数固定,会自动分行。

CSS的写法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.parent {
width: 200px;
height: 150px;
background-color: black;
display: flex;
flex-flow: row wrap;
align-content: flex-start;
}

.child {
box-sizing: border-box;
background-color: white;
flex: 0 0 25%;
height: 50px;
border: 1px solid red;
}

分享到
Template Method

Intent

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

Solution Overview

  • ConcreteClass relies on AbstractClass to implement the invariant steps of the algorithm.

Participants

  • AbstractClass (Application)

    • defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm.
    • implements a template method defining the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstractClass or those of other objects.

  • ConcreteClass (MyApplication)

    • implements the primitive operations to carry out subclass-specific steps of the algorithm.

Classification

The Template Method design pattern is not known by another name.

分享到
Strategy

Intent

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Solution Overview

  • Strategy and Context interact to implement the chosen algorithm. A context may pass all data required by the algorithm to the strategy when the algorithm is called. Alternatively, the context can pass itself as an argument to Strategy operations. That lets the strategy call back on the context as required.
  • A context forwards requests from its clients to its strategy. Clients usually create and pass a ConcreteStrategy object to the context; thereafter, clients interact with the context exclusively. There is often a family of ConcreteStrategy classes for a client to choose from.

Participants

  • Strategy (Compositor)
    • declares an interface common to all supported algorithms. Context uses this interface to call the algorithm defined by a ConcreteStrategy.

  • ConcreteStrategy (SimpleCompositor, TeXCompositor, ArrayCompositor)
    • implements the algorithm using the Strategy interface.

  • Context (Composition)

    • is configured with a ConcreteStrategy object.
    • maintains a reference to a Strategy object.
    • may define an interface that lets Strategy access its data.

Classification

The Strategy design pattern is also known as the Policy.

分享到
State

Intent

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

Solution Overview

  • Context delegates state-specific requests to the current ConcreteState object.
  • A context may pass itself as an argument to the State object handling the request. This lets the State object access the context if necessary.
  • Context is the primary interface for clients. Clients can configure a context with State objects. Once a context is configured, its clients don't have to deal with the State objects directly.
  • Either Context or the ConcreteState subclasses can decide which state succeeds another and under what circumstances.

Participants

  • Context (TCPConnection)
    • defines the interface of interest to clients.

    • maintains an instance of a ConcreteState subclass that defines the current state.

  • State (TCPState)
    • defines an interface for encapsulating the behavior associated with a particular state of the Context.

  • ConcreteState subclasses (TCPEstablished, TCPListen, TCPClosed)
    • each subclass implements a behavior associated with a state of the Context.

Classification

The State design pattern is also known as Objects for States.

分享到
Singleton

Intent

Ensure a class only has one instance, and provide a global point of access to it.

Solution Overview

  • Clients access a Singleton instance solely through Singleton's Instance operation.

Participants

  • Singleton
    • defines an Instance operation that lets clients access its unique instance. Instance is a class operation (that is, a class method in Smalltalk and a static member function in C++).
    • may be responsible for creating its own unique instance.

Classification

The Singleton design pattern is not known by another name.

分享到