在使用vue开发过程中,难免需要去本地数据地址进行请求,而原版配置在dev-server.js中,新版vue-webpack-template已经删除dev-server.js,改用webpack.d
顺晟科技
2021-06-16 10:35:32
436
开发这个插件的初衷是在做一个项目的时候,发现在移动终端上实现tab滑动的插件大多是基于swiper的,swiper的功能太强大了,而我只需要一个很小的tab滑动功能,所以需要引入200 k js,太浪费了。而且swiper不具备下拉刷新的功能,需要进行改造才能用swiper实现下拉刷新。实现功能时有很多bug。如果引入下拉刷新插件,必然会增加几十kb的js。而且这些插件对dom结构有一定的要求,不小心就会有bug。是时候在一个插件中修复bug了。
这次开发的插件只靠手势库touch.js使用原生实现函数。只有6kb大小。兼容性也不错。
其实对touch.js的依赖并不严重,只用了两个手势事件,花点时间就可以自己实现。
我只是大致测试了一下插件。如有bug,请提出。如果有不清楚的地方,也请询问。如果你觉得好,你可以给我一颗星
插件基于百度手势库touch.js修改后的手势库大小小于13k。官方文档链接找不到,引用别人写的:API文档
总结一下开发插件的原理和这次遇到的坑
实施主要分为:
确定容器结构
捕捉滑动事件(使用touch.js获取滑动方向、滑动距离和滑动速度)
实现滑动效果(这里用变换实现滑动,用transtion实现动画)
确定临界点(是否根据不同滑动距离切换页面,是否根据滑动速度切换页面)
公开监听事件(在不同状态下生成回调)
坑:
主要体现在微信和ios浏览器下拉时的弹簧效应:
选项卡幻灯片图1
这是浏览器的默认效果,可以用“e.preventDefault()”取消。然而,这将导致容器不滚动。
因此,e.preventDefault()不能直接取消默认效果。默认事件只能在特定条件下取消。条件是什么?
个条件是当它在容器的顶部时,滑动方向是向下的
第二个条件是容器底部的滑动方向向下
在这里,touch.js可以很容易的得到滑动方向,滚动条的位置也很容易计算。一开始我以为很简单,结果发现touch.js在获取滚动方向上有一定的延迟,导致次捕获的位置是最后一次,所以偶尔需要,有时候根本无法滚动。所以用touch.js获取方向是不可取的。
只能自己触摸屏幕时采集坐标,滑动时对比坐标得到方向。好了,这个bug很容易解决。这些都是微信上运行的结构。后来到了uc,发现uc甚至还有左右滑动的默认效果。
这个只能用老办法解决,加两套条件,左右滑动。根据采集到的初始点,对比滑动过程的坐标,判断是上下滚动还是左右滑动。取消默认效果。
API:
Dom结构:
div id='box '!-主集装箱-
div class='pullDownHtml '!-下拉刷新后的显示内容-
Div class='pullDownshow1 '下拉刷新/div
Div class='pullDownshow2 '刷新/div
/div
div class=' pullUpHtml '!-调出加载的显示内容-
Div class=' pullUpHtmlshow1 '上拉负载/div
Div class=' pullUpHtmlshow2 '加载/div
/div
div class='box '
div class='tab-container '
div class='s-pull '
//第1页内容
/div
/div
div class='tab-container '
div class='s-pull '
//第2页内容
/div
/div
div class='tab-container '
div class='s-pull '
//第3页内容
/div
/div
/div
/div
1.初始化
var swiper=new TabSwiper(ele,options)
//ele:容器
//选项:参数(对象)
2.选项参数
{
速度: 300,//动画速度
Threshold: 100,//上拉和下拉触发的阈值(px)
XTHRESHOLD 3360 0.3,//左右滑动触发器的阈值(0~1)默认为‘0.25’
关闭惯性:假。//是否关闭惯性滑行默认启用
isPullDown: true,//是否开启下拉刷新
isPullUp: true,//是否开启上拉加载
defaultPage: 0,//默认显示的页数
initCb:函数(){},//初始化回调
onEnd:函数(页面){},//切换页数时回调(返回当前页数)
onrelfreshstart :函数(页){},//触发下拉刷新时回调(返回当前页数)
onLoadStart:函数(页面){},//触发上拉加载时回调(返回当前页数)
onTouchmove:函数(第e页){}//正在页面上滑动回调(返回当前页数和滑动信息。可通过滑动的信息得到当前滑动的方向速度滑动的距离,进行功能扩展)
}
3、拉端(cb)方法:
swiper.pullEnd(函数(页){//返回当前页数
console.log(页面)
})
4、更改页面(页面)方法:
swiper.changePage(page)//切换页面页目标页面从0开始
5、现在索引属性:
var nowIndex=swiper.nowIndex //获取当前所在页数(只读)
下面是代码(基于es6)
若要查看es5的版本请移步(查看代码)
;(功能(窗口、文档){
//更改改变
函数changeTransform(元素,左侧,顶部){
ele。风格。transform=` translate($ { left } px,${top}px)`
ele。风格。WebKittransform=` translate($ { left } px,${top}px)`
}
class TabSwiper {
get nowIndex () {
归还这个_现在索引
}
设置nowIndex (val) {
if (val===this ._nowIndex)返回
这个_nowIndex=val
这个。选项。把这个合二为一。选项。onend(val)
}
构造函数(ele,options) {
这个_nowIndex=0
this.ele=ele
this.width=ele.clientWidth //容器宽度
this.height=ele.clientHeight //容器高度
this.totalWidth=0 //总宽度
this.box=ele.querySelector(' .方框)
这个。集装箱=ele。查询selectorall(' .制表符-容器')//容器
this.direction=' '
this.scrollTop=0
this.options=options //配置参数
这个。禁止完整=false//禁止上下拉动操作标记
this.startY=0 //起始y坐标
this.startX=0 //起始x坐标
this.isBottom=false //是否在底部
this.disX=0 //滑动X差值
this.disY=0 //滑动Y差值
这个。PullDownHTML=ele。查询选择器(' .下拉Html ')
这个。pulphtml=ele。查询选择器(' .纸浆)
这个。pulldownlhtmlheight=0//下拉的超文本标记语言高度
这个。纸浆高度=0//上拉的超文本标记语言高度
this.left=0 //向左偏移量
//初始化
this.init()
}
//初始化
init () {
这个。选项。Xthreshold=this。选项。Xthreshold | | 0.25
//设置样式
这个。ele。风格。溢出='隐藏'
这个。ele。风格。位置='相对'
this.box.style.height=' '
这个。盒子。风格。宽度=这个。集装箱。长度* 100 '大众'
this.box.style.float='left '
这个。盒子。风格。transition=' all ' this。选项。速度/1000s
这个。盒子。风格。位置='相对'
this.box.style.zIndex=2
这个。TotalWidth=this。宽度*这个。集装箱。长度;
[].foreach。叫(这个。容器,(ele)={
ele.style.float='left '
ele.style.width='100vw '
ele.style.height=' '
ele.style.overflow='auto '
ele。风格。webkitoverflow滚动=' touch '
ele。addeventlistener(' touch start ',(e)={
这个。starty=e . touch[0 ].clientY //设置起始y坐标
这个。StartX=e . touch[0].clientX //设置起始y坐标
},false)
ele。addeventlistener(' touch move ',(e)={
这个。向上滚动=这个。容器[这个。现在索引].scrollTop
这个。IsBottom=this。容器[这个。现在索引].querySelector(' .s-pull ').客户端高度=这个。向上滚动。高度
//判断滑动方向是否为上下
const DIsy=e . touch[0].客户-这个。开始
const DIsX=e . touchs[0].clientX - this.startX
//设置事件(当为顶部或底部是取消默认事件)
if((disY 0 ele。scroll top==0)| | |(DIsy 0 this。IsBottom)){
e.preventDefault()
}
//若为左右滑动时取消默认事件
if(数学。数学。ABS(disX))e . preventdefault()
},false)
})
//上下拉
if (this.options.isPullDown) {
这个。下拉HTML。风格。位置=''
这个。下拉HTML。风格。宽度=' '
这个。pulldownlhtmlheight=this。pulldownlhtml。客户高度
}
if (this.options.isPullUp) {
这个。纸浆html。风格。位置=''
这个。PullPhotml。风格。宽度=' '
这个。纸浆html。风格。底部=' 0 '
这个。pulphtmlheight=this。纸浆html客户端高度
}
//添加事件
//拖拽
touch.on(this.box,' drag ',(e)={
this.direction=e.direction
this.touchmove(e)
这个。选项。走开。选项。OnTouchmove(这个。现在索引,e) //事件输出
})
//滑动
!这个。选项。近距离接触。(这个。框中,“滑动”,(e)={
this.swipe(e)
})
//手指离开屏幕
touch.on(this.box,' touchend ',(e)={
this.touchend(e)
})
//移动至默认页面
这个。ChangePage(此。选项。默认页面| | 0)
这个。选项。初始化这个。选项。initcb()
}
//拖拽方法
touchmove (e) {
这个。盒子。风格。transition=' none '//取消动画
if((e . direction==' left ' | | e . direction==' right ')!this.disY) {
//左右滑动
this.disX=e.distanceX
变换变换(这个。框,(这个。左这个。disX),这个。disY)
} else if(!这个。disX!这个。禁止全){
//上下滑动
if(e . direction==' down '!this.options.isPullDown)返回
if(e . direction==' up '!this.options.isPullUp)返回
if((this。滚动顶部=0。direction==' down ')|(this。这是底部。方向=='向上'){
//上下拉动容器
这个。DisY=e . distaney
变换变换(这个。框,(这个。左这个。disX),这个。disY)
}
}
}
//手指离开屏幕
touchend (e) {
这个。盒子。风格。transition=' all ' this。选项。速度/1000 ' s '//开启动画
if(!这个。禁止全){
if(数学。ABS(这个。disy)这个。选项。阈值){//上下拉小于阀值自动复原
this.disY=0
变换变换(这个。框,(这个。左这个。disX),这个。disY)
}
//下拉刷新触发
if(this。滚动顶部=0 this。方向=='向下'这个。DisY=这个。选项。阈值){
这个。disy=这个。pulldownlhtmlheight
this.prohibitPull=true
//显示加载中
这个。下拉HTML。风格。可见性='可见'
这个。选项。OnRefreshstart这个。选项。OnRefreshstart(此。现在索引)//输出下拉刷新事件
}
//上拉加载触发
else if(this。这是底部。方向=='向上'数学。ABS(这个。disy)这个。选项。阈值){
这个。disy=-这个。纸浆高度
this.prohibitPull=true
//显示加载中
这个。纸浆html。风格。可见性='可见'
这个。选项。启动这个。选项。onload start(此。现在索引)//输出上拉事件
}
}
//左右滑动
if(数学。ABS(这个。DisX)这个。宽度*这个。选项。Xthreshold){
变换变换(这个。盒子,这个。左边,这个。disY)
this.disX=0
} else {
这个。左=这个。disx/数学。ABS(这个。disx)*这个。宽度
if (this.left 0) this.left=0
if(this。左=-这个。总宽度)这个。左=-(这个。总宽度-这个。宽度)
变换变换(这个。盒子,这个。左边,这个。disY)
}
this.direction='' //重置方向
这个。现在索引=数学。ABS(这个。左)/这个。宽度//计算页数
}
//快速滑动
滑动(e) {
if (e.factor 1!这个。disX!this.disY) {
if(e . direction==' left '){
这个。左边-=这个。宽度
} else if(e . direction==' right '){
this.left=this.width
}
if (this.left 0) this.left=0
if(this。左=-这个。总宽度)这个。左=-(这个。总宽度-这个。宽度)
变换变换(这个。盒子,这个。左边,这个。disY)
}
this.disX=0
这个。现在索引=数学。ABS(这个。左)/这个。宽度//计算页数
}
//关闭上下拉
pullEnd (cb) {
cb cb(this.nowIndex)
changeTransform(this.box,this.left,0)
this.disY=0
this.prohibitPull=false
}
//切换页数
变更页面(页面){
if(this。prohibitfull)返回
this.left=-page * this.width
变换变换(这个。盒子,这个。左边,这个。disY)
this.nowIndex=page
}
}
窗户TabSwiper=TabSwiper
})(窗口、文档)
29
2021-08
16
2021-06
16
2021-06
16
2021-06
16
2021-06
16
2021-06