当前位置:   article > 正文

You辉编程_WebApp&组件化_组件化与移动webapp开发

组件化与移动webapp开发


学前了解
1.Web开发:满足两个条件,一是html,css和js,代码在浏览器中运行。
2.移动web开发:html,css和js;代码在移动端(手机、平板等)浏览器中运行。
3.PC Web开发:html,css和js;代码在PC浏览器中运行。
4.APP开发:
-Application应用程序
-Native APP、Web APP和Hybrid APP(混合式App)
-------------------------------------------------
移动基础的重点知识
1.好看、能看--移动端的布局
2.可用、能用--移动端事件
3.好用--性能优化
--------------------------------------------------
移动基础 
1.移动web开发入门
(1)基本概念
-分辨率:纵向多少个点,横向多少个点
-物理像素:每个点就是物理像素
-css像素:会自动转换成物理像素
-设备像素比(dpr)=:css像素/物理像素
-标清和高清屏:dpr=1是标清,dpr>1是高清屏
-缩放:是css像素的缩放
-PPI/DPI:每英寸的物理像素点。
(2)视口--vewport
-什么是viewport,为什么需要viewport
把PC端(布局视口)的内容按比例缩小完全展示在移动端(视觉视口)。
-如何设置viewport
<meta name = "viewport" content = "wdth=375"/>
<meata name="viewport" content="width=device-width" />
最好这样设置:
<meata name="viewport" content="width=device-width,initial-scale=1" />
禁止用户缩放:
<meata name="viewport" content="initial-scale=1,user-scalable=no" />
或者限制最大缩放比例和限制最小缩放比例
<meta name="viewport" content="initial-scale=0.5,maximun-scale=0.5,minimun-scale=0.5"/>
不禁止缩放
<meta name="viewport" content="width-device-width,initial-scale=1" />
-如何获取视口的宽度
获取视口宽度
console.log(document.documentElement.clientWidth);
console.log(document.documentElement.getBoundingClientRect().width);
(3)真机查看
-通过本地服务器打开开发页面
-通过ipconfig查询IP地址,并替换页面地址中的相应部分
-关闭防火墙,在移动过设备的浏览器中输入相应的网址
(4)代发中的常用单位
-px:当需要固定宽度高度时可用。
-%:相对单位。可以用来布局,可以用设置宽度,流体布局中会用到。
-em:相对单位,设置字体大小时,1em=父元素字体的大小
-rem:相对单位,1rem = 根元素(hmtl)的字体
-vw/vh/vmax/vmin:相对单位,视口单位,可以用来布局,1vw=视口宽度的1%.
1vh=视口高度的1%
vmin:当前vw和vh中较小的一个值
vmax:当前vw和vh中较大的一个值

2.布局
(1)常用布局
-固定宽度布局(PC端常用)
(2)流体布局(百分比%)
(3)Flex弹性布局(工具,不是单独使用,要结合其他布局使用)
-Flex基础知识
什么是Flex布局
任何一个HTML元素都可以指定为Flex布局
eg:display:flex --Flex容器变成块元素
 display: inline-flex  ----Flex容器变成内联块元素

什么是Flex容器(flex container)
凡是采用Flex布局的元素,称为Flex容器

什么是Flex项目(flex item)
Flex容器的所有子元素,自动生成容器成员,称为Flex项目

什么是主轴,什么是交叉轴
默认情况下,水平方向的是主轴,垂直于主轴方向的是交叉轴。
Flex项目默认沿主轴其实排列
修改主轴的方向:flex-direction:colunm(垂直排列)
flex-direction:row(水平排列,相当于没有设,因为默认情况下就是水平排列)

-Flex容器的属性(即写在Flex容器中的属性)
flex-direction:决定了主轴的方向(即Flex的排列方向)
flex-direction:row(默认)
              :row-reverse:从右往左排
              :colunm:从上往下排
              :colunm-reverse:从下往上排

flex-wrap:默认情况下,Flex项目都排在一条轴线上,
flex-wap属性定义了如果一条轴线排不下,如何换行
flex-wap:nowrap(默认值)不换行
        :wrap:如果在不下就会换行
        :wrap-reverse:在下排往上换行

flex-flow(就是flex-direction和flex-wrap的简写方式)

justify-content:定义了Flex项目在主轴上的方式
              :flex-start:往起始轴对齐
              :flex-end:往起始轴对立方向对齐
              :center:水平居中
              :space-between:盒子之间的间隔相等
              :space-around:盒子两侧的间隔相等

align-items:定义了Flex项目在交叉轴(垂直方向)上的对齐方式。
          :flex-start:紧贴起始位置
          :flex-end:紧贴终点位置
          :center:垂直居中
          :baselin:通过基线对齐(可以看作是下划线对齐)
align-content:定义了存在多根主轴时,Flex项目在交叉轴上如何对齐,如果项目只有一根主轴线,该属性不起作用

-Flex项目的属性
order:定义了排列顺序,数组越小,排列越靠前,默认为0
order:-1,

flex-grow:定义了Flex项目在主轴方向上的放大比例,默认是0即:如果存在剩余空间,该项目也不放大
flex-grow:1在放大的同时,把剩余空间平分了

flex-shrink:的属性不为0时,当空间不足时,都将等比例缩小
flex-shrink:2

flex-basis:定义了在分配多余空间之前,Flex项目占据的主轴的大小,和width(height)差不多。
flex:felx-grow,flex-shrink和flex-basis的简写,默认值为0 1 auto
align-self:允许单个项目有与其他项目不一样的对齐方式,可以覆盖aligin-items属性
-Flex实战
(4)rem和vw布局(保持原来的宽高比)
-常用布局:
,流体布局(百分比布局)
,Flex弹性布局
,rem和vw布局
,响应式布局
,Grid网格布局
流体布局和Flex布局如果改变它的大小,宽度也会随着变化,但高度会,rem和vm高度和宽度都会随着变化。
-rem方案
,原理
宽和高可以随着屏幕大小的变化而变化
1rem=html字体大小
当屏幕变化的时候修改html的字体大小
实现等比例缩放
换算安装插件px2rem
设1rem = 10px
viewWidth/750 = ?/10px
?=viewWidth/75
,实现
//获取html元素,方便使用其方法
const docEl = document.documentElement;

const setHtmlFontSize = () =>{
  //获取当前屏幕的大小
  const viewWidth = docEl.clintWidth;
  docEl.style.fontSize = `${viewWidth/75}px`;
  setHtmlFontSize();
  window.addEventListener('resize',setHtmlFontSize,false)
}
,扩展flexible

-vw+rem布局方案(过渡方案)
,原理
viewWidth/750px(设计稿的) = ?px/10px
100vw / 750px = ?vw / 10px;
?vm = 10px * 1000vw /750px
,实现
//vw不需要借助js就能实现
html{
  font-size:1.333333vw;
}
-vw布局方案
,原理
计算出测量的值对应的vw单位的值
测量px / 750px = ?vw / 100vw 
?vw = 100vw * 测量px / 750px

原来的宽高:width:750px === 100vw(占满)
height:96px == 套用公式(100*96/750=12.8vw) 12.8vw 
这样就实现了等比例缩放
补充:优先使用vw布局方案,如果条件不允许(浏览器不兼容vw)在选择rem方案
,实现
-rem和vw布局实战
(5)响应式布局(针对不同的屏幕大小做出相应的布局)
一个网站兼容多种终端
对于不同尺寸的屏幕做出响应式(媒体查询),并进行相应的布局

-媒体查询的语法
,什么是媒体查询(Media querys)
可以帮助我们针对各种大小的屏幕写样式,让我们的页面在不同大小的屏幕上都能正常显示
@media screen and (min-width:320px){
  //min-width:320px断点,小于320px下面的代码失效
  body{
    background-color:red;
  }
}
,媒体类型
all(所有设备),screen(屏幕设备),print(打印设备),speech(屏幕阅读器,一般提供哥残障人士使用)
/*all和screen比较常用*/
@media screen adn (min-width:320px){
  body{
    background-color:red;
  }
}
/*所有设备都是可用的*/
@media all and (min-width:320px){
  body{
    background-color:red;
  }
}
@media (min-width:320px){
  body{
    background-color:red;
  }
}
,媒体查询的逻辑
与(and)   或(,)  非(not)
and:查询条件全部为真时生效
@media screen and(min-width:320px) and (max-width:375){
  body{
    background-color:red;
  }
}

或(,)
@media (screen and (min-width:355px)),(max-width:320px){
  body{
    background-color:red;
  }
}

非(not)
对当前查询条件取反
@media not screen and (min-width:320px) and (max-width:375px){
  body{
    background-color:red;
  }
}
,媒体特性
width  max-width min-width 

-webkit-device-pixel-ratio这三个的值是像素比
-webkit-max-device-pixel-ratio
-webkit-min-pixel-ratio 

orientation(屏幕的方向):landscape(屏幕横向)/portrait(屏幕的垂直方向)
@media screen and (min-width:320px){
  body{
    background-color:red;
  }
}

dpr<=2且屏幕是水平方向
@media (-webkit-max-device-pixel-ratio:2) and (orientation:landscape){
  body{
    background-color:red;
  }
}
//获取dpr
console.log(window.devicePixelRatio);

-断点和书写位置
,如何设置断点
如何设置断点Breakpoint
@media screen and (min-width:320px){
  body{
    background:red;
  }
}
//方法1:Bootstrap的断点
xs:<576px 超小屏
sm:576~768px 小屏
md:768px~992px 中屏
lg: 992px~1200px 大屏
xl:>=1200超大屏

//方法2:改变屏幕大小,当页面显示不正常(或不符合要求)的时候,就需要设置断点了
,媒体查询的书写位置
样式表(style标签或单独的css文件)

-媒体查询的策略(帮助在开发的时候如何更好的使用媒体查询)
,无策略
,PC端优先
,移动端优先
示例代码: 
 <style>
        *{
            box-sizing:border-box;/*边框涵盖在盒子里*/
            margin:0;
            padding:0;
        }
        body{
            padding-top: 200px;
        }
        img{
            width: 100%;
        }
        .row{
            width: 100%;
            display:flex;
            flex-wrap:wrap;/*超出就换行*/
        }
        .col{
            padding-top: 10px;
            padding-bottom: 10px;
            background-color: rgba(86,61,124,0.15);
            border:1px solid rgba(86,61,124,0,2);
        }
        /*
        断点
        xs:<576px 超小屏
        sm:576~768px 小屏
        md:768px~992px 中屏
        lg: 992px~1200px 大屏
        xl:>=1200超大屏
        */

        /*无策略*/
        @media (max-width:576px){
            .col{
                width:100%;
            }
        }
        @media(min-width:576px)and(max-width:768px){
            .col{
                width:50%;/*一行显示两个*/
            }
        }
        @media(min-width:768px) and (max-width:992px){
            .col{
                width:25%;
            }
        }
        @media(min-width:992px) and (max-width:1200px){
            .col{
                width:16.666667%;
            }
        }
        @media(min-width:1200px){
            .col{
                width: 8.333333%;
            }
        }

        /*PC优先*/
        /*从大到小*/
        .col{
            width:8.333333%;
        }
        @media(max-width:1200px){
            .col{
                width:16.6666667%;
            }
        }
        @media (max-width:992px){
            .col{
                width:25%;
            }
        }
        @media (max-width:768px){
            .col{
                width:50%;
            }
        }
        @media (max-width:576px){
            .col{
                width:100%;
            }
        }

        /*移动端优先*/
        /*从小到大*/
        .col{
            width:100%;
        }
        @media(min-width:576px){
            .col{
                width:50%;
            }
        }
        @media(min-width:768px){
            .col{
                width:25%;
            }
        }
        @media(min-width:992px){
            .col{
                width:16.666667%;
            }
        }
        @media(min-width:1200px){
            .col{
                width:8.333333%;
            }
        }
    </style>
</head>
<body>
    <div class="row">
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>
        <div class="col"><img src="images/1 (2).png" alt=""></div>

    </div>
-响应式布局实战
慕课首页

(6)Grid网格布局(工具)

补充:个布局方式并不孤立,根据需要可以结合使用
-什么是Grid布局
能将网页划分成一个个网格,任意组合网格,做出各种各样的布局。
-Grid基础知识
,Grid容器(container)和项目(item)
只要是设置了display:grid或inline-grid就可以称作是Grid容器,
此时Grid容器的所有子元素自动成为容器成员,称为Grid项目。

,行、列和单元格
容器中的水平 区域是行(row),垂直区域就是列(colunm),行和列称为单元格(cell)。
,网格线
划分网格的线就是网格线(grid line)
,其他(间距、区域、内容、轨道)
行间距:网格线间的距离(gap)
区域:单元格的集合(area)
内容
轨道:网格线的border值。

-Grid容器的属性
,display:grid(块元素):占满整个区域
display:inline-grid(内联块元素):如果没有设置宽高,就占自己的区域
,grid-template-rows(定义每一行的行高)/grid-template-columns(定义每一列的列宽)
,grid-auto-flow :定义项目的排列顺序
,grid-auto-rows/grid-auto-columns 
,row-gap/column-gap/gap    间距 
,grid-template-areas
,align-items:设置项目的垂直位置(上中下)
/justify-items:设置项目的水平位置(左中右)
/place-items  排列
,align-content:设置整个内容区域的垂直位置(上中下)
/justify-content:设置整个内容区域的水平位置(左中右)
/place-content 整体排列
,grid-template/grid 

-Grid项目的属性
,grid-colunm-start/grid-column-end/--横跨几个网格
grid-row-start/grid-row-end  ---同理
,grid-column / grid-row 

,grid-area 指定项目放在哪一个区域
,align-self/justify-self/place-self
-Grid布局实战


多行文字省略:
/* 多行文字的省略处理 */
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal !important;
  word-wrap: break-word;
  

3.事件和性能
-移动端事件(触摸事件)
移动端事件的发展:
很久之前是没有移动端事件的,大部分鼠标事件在移动端一样有用。
后来
,苹果推出了Touch触摸事件
,微软推出了Pointer指针事件(统一鼠标、触摸、笔)

,Touch/Pointer事件基础
Touch事件的类型:touchstart touchmove touchend touchcancel(当手指还在屏幕上时,突然有电话,就会触发touchcancel,从而取消touchend事件的触发)

const $box = document.getElementById('box');
$box.addEventListener('touchstart',startHandler,false);
function startHandler(){
  console.log('touchstart已经触发');
  //其他事件同理
}
注意事项
touch事件不会在PC端触发,而鼠标事件在PC和移动端都会触发。
即使触摸点移出目标元素,touchmove事件依然会持续触发,mousemove事件不会再触发。

Touch事件的特征检测(即判断浏览器支不支持Touch事件)
console.log('ontouchstart' in widnow);//true

,Touch/Pointer事件的event对象
event对象的常用属性
const $box = document.getElementById('box');
$box.addEventListener('touchstart',startHandler,false);
function startHandler(evt){
  console.log(evt.type);//输出当前事件类型
  console.log(evt.target);//目标元素,谁绑定的就指向谁
  //三个触摸点
  console.log(evt.touches);//记录所有触摸点
  console.log(evt.targetTouches);//记录目标元素内的手指触摸点
  console.log(evt.changedTouches);//记录所有发生改变的触摸点
}
触摸点的常用属性
const $box = document.getElementById('box');
$box.addEventListener('touchstart',startHandler,false);
function startHandler(evt){
  const touch = evt.changedTouches[0];
  console.log(touch.identifier);//标识触摸点数(几根手指触摸)
  console.log(touch.target);
  console.log(touch.screenX,touch.screenY);触摸点坐标(相对于整个屏幕而言)
  console.log(touch.clientX,touch.clientY);触摸点坐标(相对于可视区域而言)不包括滚动条
  console.log(touch.pageX,touch.pageY);触摸点坐标(相对于整个页面个而言)包括滚动条

}


如何阻止浏览器的默认行为(scrolling滚动,pinch/zoom手指进行缩放,鼠标事件等)
法1:evt.preventDefault();//会阻止所有浏览器默认行为
法2:touch-action(要写在css样式中);//用来告诉浏览器哪些触摸操作让浏览器处理,阻止其他触摸操作的默认行为。
在touch-action后写什么,就等于浏览器可以做什么
<style>
  .box{
    touch-action:auto;/*浏览器可以处理所有事情*/
    touch-action:none;/*浏览器不可以处理任何事情*/
    touch-action:pan-x;/*允许水平有滚动条*/
    touch-action:pan-y;/*允许垂直方向有滚动条**/
    touch-action:manipulation;/*只允许进行滚动和持续缩放操作,不允许双击缩放*/
  }
</style>
,移动端事件实战
-Pointer事件基础
,Pointer事件的类型
pointerover/pointerenter/pointerout/pointerleave/pointerdown/pointeromve/pointerup/pointercancel
推荐使用Pointer
$box.addEventListenet('pointerover',pointerHandler,fasle);
function pointerHandler(){};
,注意事项
Pointer事件直接继承了鼠标事件,在此基础上又添加了其他一些内容,处理Pointer事件和处理鼠标事件几乎一致。
Pointer事件在PC和移动端都会触发
触摸点移出目标元素,touchmove事件依然会持续触发,pointermove和mousemove事件不会再触发
,Pointer事件的特征检测
if('onpointerdown' in window){
  console.log('支持');
}
,Pointer事件的event对象
event对象的常用属性
function pointerHandler(evt){
  console.log(evt);
  console.log(evt.pointerId);//唯一标识符
  console.log(evt.type);//输出Pointer的事件类型
  console.log(evt.target);//输出目标元素
  console.log(evt.screenX,evt.screenY);
  console.log(evt.clientX,evt.clientY);//不包括滚动条 
  console.log(evt.pageX,evt.pageY);//包括滚动条
}

阻止浏览器的默认行为
只可以阻止scrolling,pinch/zoom,鼠标事件等默认行为
Pointer的事件处理函数中evt.preventDefault()阻止的是PC端的默认行为(不阻止scrolling,pinch/zoom,鼠标事件等默认行为,可以阻止图片拖动的默认行为)。
Pointer阻止移动端默认行为只能借助touch补丁来解决
$box.addEventListener('touchstart',startHandler,false);
funciton startHandler(evt){
  evt.preventDefault();
}
补充:手势库Hammer.js 
https://hammerjs.github.io/

总结:
 Touch                     Pointer 
touchstart(手指按下去)     pointerdown(指针按下去)
touchmove        触摸移动  pointermove
touchend         触摸抬起  pointerup 
touchcancel                pointercancel
-移动Web开发性能(页面的响应速度)优化(原则:尽可能快的渲染首屏内容,无需考虑整张页面)
页面响应速度 
打开页面到实际能够正常使用的时间:网络请求时间、页面加载和渲染的时间
与页面进行交互的流畅速度:js脚本的执行速度
,为什么需要优化移动端的性能
提升用户体验
与PC端相比,移动端网络速度慢,移动端性能比较低
,各阶段的性能优化点
1)将多个资源分布在不同域上,减少请求队列的等待时间,因为浏览器为每个域名分配的并发通道有限,
多个域意味着更多的DNS查询的时间,通常把域名拆分到3~5个比较合适
2)通过dns-prefetch减少DNS查询的时间:尝试在请求资源之前解析域名<link rel="dns-prefetch" href="//g.alicdn.com">,仅对跨域域上的DNS查找有效。
已经解析过的域名不要添加dns-prefetch 
3)减少HTTP请求数量
合并css等资源文件,但要考虑合并后资源不能过大,还有缓存问题
内联首屏的相关代码
使用缓存(浏览器缓存、localStorage等)
4)减少请求资源的大小
资源的压缩(HTML,CSS的压缩和js的压缩和混淆)
开启Gzip压缩:进一步压缩

,页面加载和渲染过程中的优化点
1)css一般在head中引入
2)js一般在body末尾引入
3)减少回流/重新布局与绘制
元素的尺寸,位置,隐藏等属性改变时,浏览器需要重新计算,就称为回流;
元素的外观,风格等属性改变时,浏览器只需要重新绘制,就称为重绘;
回流一定会引起重绘,重绘不一定会引起回流。

,js脚本中的优化点
1)DOM操作优化
2)事件优化
3)图片给懒加载和预加载
,具体的性能优化策略
1)图片优化(减少HTTP的请求数量)
尽量用css来绘图https://www.webhek.com/post/40-css-shapes.html
合并小图标(css sprites)
将小图标内嵌到html中

减少请求资源的大小
使用图标字体代替简单的图标
图片压缩
选择合适的图片大小
选择合适的图片类型

2)动画的优化
优先使用css3:transition(过渡)、animation(动画)、translate3d(运动)
js:requestAnimationFrame

3)css优化
选择器的优化
不要使用嵌套过多于发杂的选择器,可以通过设置样式直接选择不用嵌套
保持简单,不要画蛇添足
避免过多的使用通配符选择器
移除没有用的空的匹配样式(样式里没有任何的属性)

其他优化
提取公共部分
避免使用css @import导入css

4)DOM优化 
渲染优化
较少DOM元素的数量和嵌套层级
尽量避免使用table布局,用其他标签代替

选择器优化 
优先使用id来获取单个元素document.getElementById('box');
获取多个元素时,尽量直接通过元素本身的className获取(eg:li)document.getElementByClassName('list');

减少DOM操作次数的优化
总是将选择器的选择结果缓存起来(缓存在变量里)

const todoDatas = ['吃饭','睡觉','写代码'];
const $list = document.getElementByClassName('list');

for(cont item of todoDatas){
  $list.innerHTML += `<li class='item'>${item}</li>`
}
避免在循环中多次使用innerHTML,在循环结束后使用一次
let html = '';
for(const item of todoDatas){
  html += `<li class='item'>${item}</li>`;
}
$list.innerHTML = html;

//创建元素场景
for(cont itme of todoDatas){
  //创建li元素
  const $li = document.createElement('li');
  //给li标签加选择器名
  $li.className = 'item';
  $li.innerhTML = item;

  $li.appendChild($li);
}
要使用DocumentFragment优化多次的appendChild

const $liFragment = document.createDocumentFragment();

for(cont itme of todoDatas){
  //创建li元素
  const $li = document.createElement('li');
  //给li标签加选择器名
  $li.className = 'item';
  $li.innerhTML = item;
  
  $liFragment.appendChild($li);
}

$list.appendChild($liFragment);

不要直接通过JS修改元素的style,通过添加和移除class修改元素样式
.active{
  width:200px;
  height:200px;
  background-color:red;
}

const box = document.getElmentById('box');

active.classList.add('active');

注意强制回流

5)事件代理(事件委托)
什么是事件代理
原本在子元素上监听的事件委托给父元素,让父元素监听
事件代理的实现

6)事件稀释
什么是事件稀释
有些事件在一段时间内会发生多次触发,事件稀释就是减少这些事件的触发频率
比如:scroll,resize mousemove,touchmove等
window.addEventListener('scroll',debounce(scrollHandler),false);
window.addEventListener('resize',handler,false);
function scrollHandler(evt){
  console.log(evt.type);
}
事件稀释的方法
,防抖(debounce):在某个时间期限内,事件处理函数只执行一次
function debounce(fn,miliseconds = 250,context){
  let timer = null;

  return function(...args){
    const self = context || this;

    if(timer){
      clearTimeout(timer);
    }

    timer = setTimeout(()=>{
      fn.aply(self,args);
      timer = null;
    },miliseconds)
  };
}
,节流

7)图片的懒加载:又叫图片延迟(按需)加载,在需要的时候加载图片
图片懒加载的实现
4.其他
-移动Web开发常见问题
1)1px边框
高清屏下,1px边框“变粗”的原因:
并不是真的变粗了,而是设计想要的1像素,不是程序员眼中1css像素,而是1物理像素
如果dpr=2,设计实际想要的就是1px/2=0.5px

解决方案
和设计商量,如果不在意这个问题,不用去管。
直接设置细边框。(会有兼容性问题)。
伪类+transform(推荐)
eg:@media(-webkit-min-device-pixel-ratio:2){
  .border-1px{
    position:relative;
    border:none;
  }
  .border-1px::after{
    content:'';/*一定要写这个不然伪类不会生效**/
    position:absolute;
    top:0;
    left:0;
    width:200%;
    height:200%;
    background-color:rgba(255,0,0,0.5);
    border-bottom:1px solid #ccc;
    transform-orgin:0 0;
    transform:scale(0.5);/*缩小*/
  }
}

2)click事件300ms延迟
延迟的原因:double-tap to zoom双击缩放
解决方案:不使用click事件,把click事件中要处理的放到touchstart或touchend中处理。
const $btn = document.getElementById('btn');
//立即触发
$btn.addEventListener('touchstart',()=>{
  const.time('click');
},false);
$btn.addEventListener('click',()=>{
  const.timeEnd('click');
  console.log('提交表单');
},false);
3)Touch事件点击穿透
点击穿透的原因:移动端Touch事件会立即触发,而click事件延迟一段时间触发。
解决方案:遮罩层不要立即消失
4)移动端图片
img 
背景图片

-Swiper触摸滑动插件
1)开源、免费、强大的触摸滑动插件
2)在移动端和PC端使用
3)实现移动端和PC端的大部分滑动功能
,幻灯片
,Tab选项卡
,页面滑动切换
1.swiper的使用方法
1.1加载swiper文件
        加载swiper-bundle.min.js和swiper-bundle.min.css文件
        1.2.完成swiper的html结构和css样式
        1.3初始化swiper
2.swiper的常用API
1)Swiper初始化
用于初始化一个swiper,返回初始化后的swiper实例
const swiper = new Swiper('#swiper',{
  initalSlide:0,//索引值
  direction:'horizontal',//水平切换
  direction:'vertical',//垂直方向切换
  speed:300,//切换速度
  effect:'slide',//位移切换
  effect:'fade',//淡入
  fadeEffect:{
    crossFade:true;//当下一个淡入的时候,上一个淡出
  },
  grabCursor:true,
  freeMode:true,//自由滑动
  loop:true,//首尾互联模式
  on:{
    init:function(swiper){
      //swiper就是实例化后返回的对象
      console.log(this===swiper);//true
      //属性
      console.log(this.activeIndex);//当前活跃的索引
    },
    slideChangeTransitionStart:function(swiper){
      console.log('slideChangeTransitionStart');
    },
    slideChangeTransitionEnd:function(swiper){
      console.log('slideChangeTransitionEnd');
    }
  }
});
2)基础配置
const swiper = new Swiper("选择器",{在此处进行一些配置})
3)事件 
init初识化后执行
slideChangeTransitionStart从当前slide开始过渡到另一个slide时执行
slideChangeTransitionEnd从一个slide过渡到另一个slide结束时执行
4)属性
5)方法
slideNext()/slidePrev()切换到下/上一个滑块
slideTo()控制Swiper切换到指定slide
6)控制
autoplay自动切换
pagination使用分页器导航
navigation使用前进后退按钮来控制Swiper切换
scrollbar为swiper增加滚动条
keyboard开启键盘来控制swiper切换
mousewheel开启鼠标滚轮控制swiper切换


======================================================

组件化开发

=================

1.模块化和组件化
-模块化:
把复杂的功能,拆分成一个一个的小块去实现,最后把它组装起来形成一个完整的功能。
-组件化
组件:一个整体的组成部分。
组件化:把一个项目分成一个一个的组件。
-需要使用webpack
项目目录:
> node_modules
> src:开发的代码所有都放在这里
package.json
package-lock.json 
webpack.config.js 

--------------------------------------
其中:
src:
> api:所有与前后端通行的api都放在这里(eg:ajax封装)
> assets:CSS,img,字体等资源。
> components:公共组件(所有页面都会用到的组件)
> pages:存放开发的页面,如首页,详情页等。

-技术选型
开发语言:ES6
获取数据:Ajax
打包工具:webpack
模板引擎:art-template
-语法1:
<body>
    <div id="content"></div>
    <br />
    <div id="otherContent"></div>

    <ul id="list"></ul>

    <script src="https://unpkg.com/art-template@4.13.2/lib/template-web.js"></script>
    <!-- 准备输出模板 -->
    <script id="tpl-1" type="text/html">
        {{value}}
        <br>
        {{data.key}}
        <br>
        {{a+b}}

        <!-- {{data}}可以输出所有数据 -->
        {{$data}}
        {{data.value}}
        {{data.key}}
        {{data.data}}
        <!-- 原样输出,不会有样式 -->
        {{text}}
        <!-- 要输出样式在之前加@ -->
        {{@text}}
    </script>

     <!-- 2.条件语法 -->
    <script id="tpl-2" type="text/html">
        {{if sex === 'male'}}
        男
        {{else if}}
        女
        {{esle}}
        其他
        {{/if}}
    </script>

  <!-- 3.循环 -->
    <script id="tpl-3" type="text/html">
        {{each students}}
        <li>{{$value.name}} {{$value.age}} {{$value.sex}}</li>
        {{/each}}
    </script>

     <!-- 4.子模板 -->
    <script id="tpl-4" type="text/html">
        <!-- 公共头部 -->
        {{include 'tpl-4-header'}}
        <p>首页</p>
        <!-- 公共页脚 -->
        {{include 'tpl-4-footer'}}
    </script>

    <!-- 向子模板传参 -->
    <script id="tpl-4-2-header" type="text/html">
      <header>我是{{page}}公共头部</header>
    </script>
    <script id="tpl-4-2-footer" type="text/html">
      <footer>我是{{page}}公共底部</footer>

      <!-- 主要模板 -->
    <script id="tpl-4-2-index" type="text/html">
      <!-- 公共头部 -->
      {{include 'tpl-4-2-header'}}
      <% include('tpl-4-2-header',{page:'首页'}) %>
      <p>首页</p>
      <!-- 公共底部 -->
      {{include 'tpl-4-2-footer'}}
      <% include('tpl-4-2-footer',{page:'首页'}) %>
    </script>
    <!-- 列表页 -->
    <script id="tpl-4-2-index" type="text/html">
      <!-- 公共头部 -->
      {{include 'tpl-4-2-header'}}
      <% include('tpl-4-2-header',{page:'列表页'}) %>
      <p>列表页</p>
      <!-- 公共底部 -->
      {{include 'tpl-4-2-footer'}}
      <% include('tpl-4-2-footer',{page:'列表页'}) %>
    <script id="tpl-4-header" type="text/html">
        <header>我是公共的头部</header>
    </script>
    <script id="tpl-4-footer" type="text/html">
        <footer>我是公共的页脚</footer>
    </script>
    <script>
    // 官方文档   http://aui.github.io/art-template/zh-cn/docs/
    //1.模板引擎的输出  
    const content = document.getElementById('content');
    content.innerHTML=template('tpl-1',{
        value:1,
        data:{
            key:2
        },
        a:3,
        b:3,
        text:'<strong>重点内容</strong>'
    });
    
   -------------------------------------
   //2.条件语法
    //2.条件语法
    const content = document.getElementById('content');
    content.innerHTML = template('tpl-2',{
        sex:'male'
    })

    ----------------------------------------
    //3.循环语法
    // 学生数据
    const students = [
        {
          name: 'Alex',
          age: 18,
          sex: 'male'
        },
        {
          name: '张三',
          age: 28,
          sex: 'male'
        },
        {
          name: '李四',
          age: 20,
          sex: 'female'
        }
      ];

      const list = document.getElementById('list');
      list.innerHTML = template('tpl-3',{
          'students':students
      })
   
   //4.子模板
      const content = document.getElementById('content');
      //即使没有参数也要传空对象
      content.innerHTML = template('tpl-4',{});

      //向子模板传参
      //如果需要向子模板传参,就要使用原始语法
      const content = document.getElementById('content');
      content.innerHTML = template('tpl-4-2-index',{});

      //列表页
      const otherContent = document.getElementById('otherContent');
      otherContent.innerHTML = template('tpl-4-2-list',{});
    </script>
  </body>

-在webpack中使用art-template 
安装webpack的相关包:npm install --save-dev webpack-cli@3.3.12 webpack@4.44.1
安装art-template相关依赖:npm install art-template@4.13.2
2.在项目中使用Ajax获取服务器端数据

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/295615
推荐阅读
相关标签
  

闽ICP备14008679号