开发目的,使下拉动作和数据反馈执行分离,目前各组件库都需要loading负值阻断弹回,造成页面显示阻塞。
初始化
new Touch("#app",{option}).then() //应当在#app 元素生成后执行
- 在入口页面添加#app,{option},then 都为非必填
- vue页面在 methods 中增加?onTouch 方法,在拉取下拉刷新后回掉
/**
* @name 下拉刷新
* @template new Touch("#app",{option}).then()
* @param {arguments[0]} String 非必填(建议填如id),下拉动态负载,默认body
* @param {option} Object 非必填
* @param {lazy} Number {lazy:100} 下拉响应惰性值默认 100
* @param {time} Number {time:1000} 数据防抖惰性值默认 1000
* @returns then Function xxx.then(arg=>arg) //下拉刷新后回掉
* @name vue页面注入
* @template { methods: {?onTouch }}
*/
import Vue,{callHook} from "vue";
let setT,$event = new Vue();
class Touch {
constructor(id,opt={ }){
this.main();
this.createElement(id);
this.generators=new Set();
this.next = null;
this.status={};
this.opt = Object.assign({
lazy:100 ,//下拉取惰性
time:1000,//数据防抖动值
},opt)
return this;
}
main(){
this.options = {
start:0,
move:0,
end:0,
isTrue:false,//是否拖动到有效值
}
}
then(fun){
this.generators.add(fun);
return this;
}
createElement(id){
const doc = (document.documentElement||document.body);
this.self = id? document.querySelector(id):doc;
this.parent = this.self==doc? this.self:this.self.parentNode;
this.element = document.createElement("div");
Object.assign(this.element.style,{
"textAlign":"center","height":"0","transform":"translateY(50%)","position":"fixed",
"top":"0","left":"0","width":"100%","zIndex":"1","overflow":"hidden"
})
this.arrow = document.createElement("span");
Object.assign(this.arrow.style,{
display:"inline-block",
borderRadius:"50%",
border:"#c00 solid 2px",
borderTop:"none",
width:"50px",
height:"50px",
transform:"translate3d(0,0,0),rotate(0deg)",
})
this.element.appendChild(this.arrow);
let first = this.parent.children[0];
this.parent.insertBefore(this.element,first);
this.addEvent();
}
//事件绑定
addEvent(){
// window.addEventListener("scroll",this.scrollEvent.bind(this),false);
window.addEventListener("touchstart",this.touchstart.bind(this),false);
window.addEventListener("touchmove",this.touchmove.bind(this),false);
window.addEventListener("touchend",this.touchend.bind(this),false)
}
scrollEvent(event){
// console.log(this.parent)
// console.log(self.scrollTop);
}
touchstart(event){
//console.log(event)
this.touchend();
let {pageX,pageY} = event.targetTouches[0];
// console.log(this.parent)
// console.log(pageY,this.parent.scrollTop)
// console.log(this.parent.scrollTop)
if(this.parent.scrollTop<=0){
Object.assign(this.options,{
start:pageY,
touchs:true
})
}
//console.log("start",event.targetTouches)
}
touchmove(event){
let {pageX,pageY} = event.targetTouches[0];
if(!this.options.touchs){
this.options.isTrue=false;
return
}
this.options.move = pageY;
// console.log("move",event.changedTouches)
let height = pageY-this.options.start;
if(height<0){
// console.log(height);
this.options.isTrue=false;
this.touchend();
return
}
if(height>100){
let _height = height-this.opt.lazy;
this.options.isTrue=true;
this.setTransform(_height);
}
//指针归位
this.next = this.generators.values();
}
touchend(event){
this.setTransform(0); //位置复位
if(setT){ clearTimeout(setT)}
setT = setTimeout(()=>{
event&& //用户事件
this.options.isTrue&& //有效拖动
this.runNext(); //执行回掉
},this.opt.time);
//复位
Object.assign(this.options,{
start:0,
move:0,
end:0,
touchs:false
})
}
runNext(item=this.next,...res){
this.options.isTrue=false;
let next = item.next();
if(!next.done){
let fun = next.value(res); //执行
if(/Promise/ig.test(Object.prototype.toString.call(fun))){
fun.then((params)=>{
this.runNext(item,params);
});//处理promise
}else{
this.runNext(item,fun);//处理普通事件
}
}else{
$event.$emit("?onTouch",res);//发送事件给组件
//指针归位
this.next = this.generators.values();
}
}
setTransform(height){
Object.assign(this.self.style,{
transform:`translateY(${height}px)`
})
Object.assign(this.element.style,{
height:height>=100? "100px":"0"
// height:height+"px"
})
Object.assign(this.arrow.style,{
transform:`rotate(${height}deg)`
})
}
}
export function install (vue,options){
console.log(callHook);
vue.mixin({
beforeCreate() {
let self = this;
$event.$on("?onTouch",(arg)=>{
//this.$mount(arg)
this["?onTouch"]&&this.?onTouch(arg);
})
}
})
}
Vue.use(install)
export default Touch;