移动web开发基础
视口
设置视口和最大最小缩放
获取视口 document.documentElement.clientWidth ||window.innerWidth||document.documentElement.getBoundingClientRect();
获取设备缩放比:wi ndow.devicePixelRatio
box-sizing: border-box 向内压缩 cont ent-box 向外扩张
flex弹性盒属性
display :flex |flex-inline
flex-direction:row |row-reverse|column|column-reverse
flex-wrap:nowrap 不换行| wrap| wrap-reverse
flex-flow 是flex-direction和flex-wra p的简写形式:默认值为row nowrap
justify-content (定义了项目在主轴(默认x轴)上的对齐方式):flex-start(左对齐)|flex-end(右对齐)|center(水平居中)|space-between(两端对齐边界,项目之间的间隔相等)|space-around(每个项目之间的间隔相等)
align-items (定义了项目在交叉轴(默认y轴)上如何对齐){flex-start|flex-end|center(垂直居中)|baseline|stretch(默认,如果项目未设置高度或者为auto,将占满整个容器的高度)}
align-content (定义了多根轴线在交叉轴上的对齐方式,如果项目只有一根轴线即仅有单行盒子,该属性不起作用):stretch|center|flex-start|flex-end|space-between|space-around
什么是flex项目( flex item) ? ★
flex容器的所有子元素自动成为容器成员,称为flex 项目,注意虽然子元素的容器能够进行弹性布局,但是子元素内部的文字等内容仍然是block,需要设置为display:flex,才可以使用justify-content等属性
1、order:(定义项目的排列顺序,数值越小排的越前)
2、flex- grow:属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大,如果所有项目的flex -grow属性都为1,则它们将等分剩余空间(如果有的话),如果一个项目的flex grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍
3、flex- shrink 属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
如果所有项目的flex:shrink属性都为1,当空间不足时,都将等比例缩小
如果一个项目的flex shrink属性为0,其他项目都为1,则空间不足时,前者不缩小
负值对该属性无效。
4、flex-basis 属性(优先级高于width)
flex- basis属性定义了在分配多余空间之前,项目占据的主轴空间( main size )
浏览器根据这个属性,计算主轴是否有多余空间
它的默认值为auto,即项目的本来大小
.item { flex basis:
- flex属性
flex属性是flex- grow, flex shrink和flex- basis的简写,默认值为0 1 auto
后两个属性可选
该属性有两个快捷值: auto (1 1 auto)和none (0 0 auto)
.item { flex none |
6、align-self 属性
align self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align items属性
默认值为auto,表示继承父元素的align items属性,如果没有父元素,则等同于stretch
.item { align self: auto | flex start | flex end | center | baseline I stretch; }
媒体查询
意义:一套样式不可能适应各种大小的屏幕,针对不同的屏幕大小写样式,让我们的页面在不同大小的屏幕上都能正常显示
语句:单条件查询:@media screen and (min-width:900px) || @media (min-width:900px){xxx{} }
? 多条件查询:@media screen and(min-width:900px) and (max-width:1024px)
? @media screen and(min-width:900px) ,screen and (max-width:1024px)
?
媒体类型:all(default) screen/print(打印预览)/speech(屏幕阅读器残障人士用)
媒体查询逻辑: 与(and) 或(,) 非(not)(not条件在遇到‘或‘和结尾时中断)
媒体特征表达式:
常用:width/max-width/min-width
-webkit-device-pixel-ratio/-webkit-max-device-pixel-ratio/-webkit-min-pixel-ratio 设备缩放比
orientation
landscape(横屏)/portrait(竖屏)
不常用:height
device-width/device-height
screen.width/screen.height
aspect-ratio 视口的宽高比
媒体策略应用写法
断点
XS: < 576px
sm: 576px. ~.768px
md: 768px ~ 992px
lg: 992px ~ 1200px
xl: > 1200px
@media(max-width:576px){.col{width:100%;}}
@media(min-width:576px) and(max-width:768px){}
@media(min-width:769px) and(max-width:992px){}
@media(min-width:993px) and(max-width:1200px){}
@media(min-width:1201px) {}
移动端常用单位
px/%/em/rem/vw/vh
em表示相对尺寸,其相对于当前对象内文本的font-size
rem也表示相对尺寸,其参考对象为根元素
的font-size,因此只需要确定这一个font-sizevw:viewport-width
vh:viewport-height
//根据视口大小调整各元素大小
window.onresize = setRemUnit;
function setRemUnit() {
var docEl = document.documentElement;
var viewWidth = docEl.clientWidth;
docEl.style.fontSize = viewWidth / 375*20 + ‘px; //默认了一个在375的视口宽下fontsize为20px的比例
// 1rem = 20px
}
响应式布局
技术目的:一份源码兼容多种终端 ;
原理:对不同屏幕尺寸(大小)做出响应,并进行相应布局的一种移动Web开发方式
实现方式:栅格系统,媒体查询
通过col-1~12 col-sm-1~12 col-md-1~12 col-lg-1~12 col-xl-1~12 来实现,那么为什么要分成四种呢?因为可能在不同大小的屏幕下所需要设置的占比不同,比如小屏我只想要他一张图片占据col-sm-12,但是在中屏,我想他占据一半,这样我就可以设置一个col-md-6,实现在不同屏幕下有不同的布局效果
优点
1、不用为每种终端开发一个网站
2、一个网站能够兼容多种终端
缺点
1、需要兼容各种终端,工作量大,效率低下
2、代码累赘,加载时间加长
为了所有终端开发的
3、在特定终端会出现无用代码
适用场景:企业站等展示性质的网站,结构比较简单的页面
不适用:结构复杂交互多的页面,功能性的页面
移动端屏幕适配
作用:使页面在移动端各种大小的屏幕上都能够正常显示的一种移动端开发方案
方法原理:通过设置resize事件更改html的font-size的值间接影响rem的值达到适配移动端
(function () {
‘use strict‘;
setRemUnit();
window.addEventListener(‘resize‘, setRemUnit);
function setRemUnit() {
var docEl = document.documentElement;
var ratio =18.75;
var viewWidth = docEl.getBoundingClientRect().width |I window.innerWidth;
docEl.style.fontSize = viewWidth / ratio + ‘px‘;}})()
痛点:1px问题:1px边框在缩放比为2的设备中会变成2px,解决方法,判断dpr大小动态生成viewport meta
改良版
//flexible.js
(function () {
‘use strict‘;
//devicePixelRatio 通过dpr来决定scale(缩放比)的大小 scale=1/dpr
var docEl = document.documentElement,
viewportEl = document.querySelector(‘meta[name="viewport"]‘),
dpr = window.devicePixelRatio || 1,
maxWidth = 540, //设置最大最小值提升观感,防止元素无止境放大或缩小
minWidth = 320;
dpr = dpr >= 3 ? 3 : (dpr >= 2 ? 2 : 1); //dpr限制在1,2,3三个值
docEl.setAttribute(‘data-dpr‘, dpr);
docEl.setAttribute(‘max-width‘, maxWidth);
docEl.setAttribute(‘min-width‘, minWidth);
//②通过scale来解决1px问题
var scale = 1 / dpr,
content = ‘width=device-width, initial-scale=‘ + scale + ‘, maximum-scale=‘ + scale + ‘, minimum-scale=‘ + scale + ‘, user-scalable=no‘;
if (viewportEl) {
viewportEl.setAttribute(‘content‘, content);
} else {
viewportEl = document.createElement(‘meta‘);
viewportEl.setAttribute(‘name‘, ‘viewport‘);
viewportEl.setAttribute(‘content‘, content);
document.head.appendChild(viewportEl);
}
setRemUnit();
window.addEventListener(‘resize‘, setRemUnit);
function setRemUnit() { //③解决高宽等缩放比问题
var ratio = 18.75;
var viewWidth = docEl.getBoundingClientRect().width || window.innerWidth;
// console.log(viewWidth);
if (maxWidth && (viewWidth / dpr > maxWidth)) { //通过scale缩放之后视口大小会发生变化,除以dpr以获最初的视口大小
viewWidth = maxWidth * dpr; //设置成maxwidth或者minwidth之后视口还是会继续改变,但是比例不会变了
} else if (minWidth && (viewWidth / dpr < minWidth)) {
viewWidth = minWidth * dpr;
}
docEl.style.fontSize = viewWidth / ratio + ‘px‘;
}
})();
什么是dpr
在早先的移动设备中,并没有DPR的概念。随着技术的发展,移动设备的屏幕像素密度越来越高。从iphone4开始,苹果公司推出了所谓的retina视网膜屏幕。之所以叫做视网膜屏幕,是因为屏幕的PPI(屏幕像素密度)太高,人的视网膜无法分辨出屏幕上的像素点。iphone4的分辨率提高了一倍,但屏幕尺寸却没有变化,这意味着同样大小的 屏幕上,像素多了一倍,于是DPR = 2
实际上,此时的CSS像素对应着以后要提到的理想视口,其对应的javascript属性是screen.width/screen.height
而对于设备像素比DPR也有对应的javascript属性window.devicePixelRatio
以iphone8为例,iphone8的CSS像素为375px677px,DPR是2,所以其设备像素为750px1354px
我的理解:①在原本css像素为375,dpr为2的情况下,1px问题会扩展为2px,这时候获取dpr,手动修改scale使得css像素扩充为750,这时候解决了1px问题而且不影响屏幕的分辨率,一个css像素对应一个设备像素,由此屏幕像素的适配问题解决。②元素大小适配问题,通过rem来进行适配 //具体方案在flexible.js
移动端事件
-
触摸事件(重点)
touch事件
pointer
-
手势事件(兼容性问题大)
-
传感器事件(兼容性问题大)
HAMMER.JS 高级手势事件库
移动端调试和终端检测
工具:浏览器、远程调试工具Vorlon.js(要和服务器搭配搭配使用例如phpstudy)
终端检测作用:页面跳转、加载相应资源
npm install -g cnpm --registry=https://registry.npm.taobao.org
多终端同步工具
Browser-sync
原理:浏览器请求到达192.168.0.103:3000端口时, node此时相当于一个反向代理,node会向localhost:80获取内容,然后再添加一段javascript代码,如下然后,javscript代码打开tcp通道和node保持链接,当对方有动作时,通过这个打开的通道发送通知,例如当node检测到文件有改动了,会通过tcp通道通知浏览器刷新;
当javascript代码检查到浏览器有可以上报的动作时(例如屏幕滚动),会通过这个tcp通道上报给node,由node分发给其它终端,从而实现多终端屏幕同时滚动
终端检测
navigator.userAgent
移动端常见问题总结
caniuse.com html/css/js 兼容性 查询
html标签兼容性解决方法:html5shiv.js
css3兼容性解决方法:①通过手动添加各厂商前缀或者使用工程化手段自动生成css3代码
②modernizr.com 勾选需要检测的属性生成js文件,通过html的class名判断是否支持该属性,分别写支持和不支持的css样式
js兼容性解决方法:特性检测
例 if(requestAnimationFrame){} //如果不存在会报错
if(window.requestAnimationFrame){} //如果不存在只会报undefined
移动端单击300ms延迟问题解决:部分浏览器可以通过content="device-width" 解决 fastclick.js
单行多行文字溢出:
非flex布局:.text-ellipsis{overflow:hidden;
text-overflow: ellipsis;
white-space;nowrap (不换行) }
flex布局:不要让内容处于弹性盒中,可以增加一层span或者其他标签使其脱离弹性盒
自定义内容行数:.mulltilline-ellipsis{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
white-space: normal !important;
word-wrap: break-word;
}
水平居中和垂直居中
margin :0 auto | |
position+margin | |
position+transform:translate | |
flex justify-content align-items | |
多行文字向左对齐水平居中 flex justify-content align-items | |
多行文字中间对齐水平居中 text-align |
移动/PC端性能优化
目的:提升用户体验
性能优化策略分类
- 网页资源请求与加载类
- 网页渲染类
- javascript脚本类
尽量减少http请求的原因,tcp通道建立需要花费时间比较长,而实际传输时间并不多,所以尽量减少http请求有助于提高访问速度
CSS
css文件尽量在头部引入
//css内联:
优点:
减少HTTP请求
缺点:
1.没办法复用(缓存)
2.使得HTML文件变大,加载时间变长
3.代码都写到HTML文件中,不利于后期的维护
工程化的手段可以解决这个问题,源码到可以上线的代码
//通过外部文件引入
优点:
1.很好的复用代码
有效利用浏览器的静态资源缓存
2.代码分离,利于后期维护
缺点:
增加了HTTP请求
结论:将首屏所需要加载的css和js使用内联的方式引入,而其他则使用外部文件
CSS-选择器优化
①减少选择器的精细程度,提高类名的语义化程度,从而减少浏览器的工作 如 container grandfather father son div 在不发生歧义和权重的前提下应该改成container-son div
②不使用空的css选择器,因为浏览器仍然会解析,属性选择器也最好不适用,因为性能低
③合并公共属性
④避免使用 import:url(‘./‘) 因为这会发起请求
⑤移动端使用flex布局会比使用float消耗的资源少
JS
和dom无关以及优先级高的脚本可以放在前面,除此之外都可以丢在后面
DOM
①能用id寻找dom尽量用id,不仅是js,css也是
②使用createDocumentFragment作为中间节点临时保存html代码,最后再插入到目标dom元素中,中间节点创建后一开始不存在于文档流中,每次增添dom节点到中间节点不会更新html页面
③使用cloneNode(true) 深拷贝节点,减少重复创建新节点并设置属性的工作
④查看dom元素的属性也算是操作dom元素
⑤尽量减少重排和重绘过程,(重排过程包括重绘)
事件优化
①使用事件代理或者事件委托代替事件绑定
②事件节流/事件稀释 对于触发频率极高的事件可以增添一个计时器,每次事件发生刷新计时器,计时倒数成功后才触发事件
var timer=null;
window.addEventListener(‘scroll‘,function(e){
clearTimeout(timer);
timer=setTimeout(function(){
console.log(1)},500); //执行内容
},false);
资源按需加载(懒加载/延迟加载)
①先将需要加载的资源的img.src设置为loading.gif
②设置滚动事件或者查看是否在可视区范围内用于触发加载图片
③将资源地址置放于json文件中,也可以放在元素的data-src上面
function isInVisibleArea(el){
var rect=el.getBoundingClientRect(); //方法返回元素的大小及其相对于视口的位置。
return rect.bottom >0 && rect.top <window.innerHeight &&rect.right>0 &&rect.left<window.innerWidth;
//top 太大的话会直接超出下边界
}
//脚本懒加载
loadProduct();
window.addEventListener(‘scroll‘, loadProduct, false);
function loadProduct() {
if (isInVisibleArea(document.getElementById(‘product‘))) {
var script = document.createElement(‘script);
//setTimeout(function () {
script.src = ‘js/loadProduct.js‘;
//}, 1000); //延迟1s模拟网络环境
document.body.appendChild(script);
window.removeEventListener(‘scroll, loadProduct, false);
}
}
IMG
特点:大、多
HTTP请求大,多
解决方法:图片压缩处理,使用更高压缩比格式的图片(webp)
尽量少用图片,使用图标字体代替图片图标
CSS画图
ZEPTO
移动段微缩版jquery
动画文件:fx.js 和 fx_methods.js
touch模块:touch.js