自定义封装移动端事件库

简介: 笔记

封装移动端事件库的意义



移动端使用click事件会有延迟

有许多左滑或者右滑的操作,原生js没有

有时业务会需要长按事件,原生js没有

开始封装


思路分析



既然是库,那么可以先写一个匿名自执行函数(保护内部变量不受污染,定义和调用合为一体)

内部结构分析

(a) 是需要外部调用,所以需要一个对外提供的接口

(b) 需要选取元素,进行操作,所以做一个初始方法

© 其它原型方法,比如点击,长按,滑动


开始操作



第一步:匿名自执行函数

  (function (window){ 
    //传入window,提高变量的查找效率
  })(window);

第二步:内部架构搭建

对外提供的接口 + 初始化方法

(function (window){ 
  function myMobile(selector){  //对外提供的接口。
        //调用这个函数的原型对象上的_init方法,并返回
        return myMobile.prototype._init(selector);
    }
    myMobile.prototype = {
        /*初始化方法,获取当前查找的对象*/
        _init: function (selector){
            if (typeof selector == "string"){
                //把查找到的元素存入到这个原型对象上。
                this.ele = window.document.querySelector(selector);
                //返回值其实就是原型对象。
                return this;
            }
        },
    }
  })(window);

第三步:原型方法添加(全部的代码)

(function (window){  
    function myMobile(selector){  
        return myMobile.prototype._init(selector);
    }
    myMobile.prototype = {
        /*初始化方法,获取当前query对象的方法*/
        _init: function (selector){
            if (typeof selector == "string"){
                //把查找到的元素存入到这个原型对象上。
                this.ele = window.document.querySelector(selector);
                //返回值其实就是原型对象。
                return this;
            }
        },
        /*单击事件:
         * 为了规避click的300ms的延迟,自定义一个单击事件
          触摸时间小于500ms为单击事件
         * */
        tap: function (handler){
            this.ele.addEventListener("touchstart", touchFn);
            this.ele.addEventListener("touchend", touchFn);
            var startTime,
                endTime;
            function touchFn(e){
                e.preventDefault()
                switch (e.type){
                    case "touchstart":
                        startTime = new Date().getTime();
                        break;
                    case "touchend":
                        endTime = new Date().getTime();
                        if (endTime - startTime < 500){
                            handler.call(this, e);
                        }
                        break;
                }
            }
        },
        /**
         * 长按
         * @param handler
         * 大于500ms为长按事件
         */
        longTag: function (handler){
            this.ele.addEventListener("touchstart", touchFn);
            this.ele.addEventListener("touchmove", touchFn);
            this.ele.addEventListener("touchend", touchFn);
            var timerId;
            function touchFn(e){
                switch (e.type){
                    case "touchstart" :  //500ms之后执行
                        timerId = setTimeout(function (){
                            handler.call(this, e);
                        }, 500)
                        break;
                    case "touchmove" :
                        //如果中间有移动也清除定时器
                        clearTimeout(timerId)
                        break;
                    case "touchend" :
                        //如果在500ms之内抬起了手指,则需要定时器
                        clearTimeout(timerId);
                        break;
                }
            }
        },
        /**
         * 左侧滑动。
         * 记录手指按下的左边,在离开的时候计算 deltaX是否满足左滑的条件         
         */
        slideLeft: function (handler){
            this.ele.addEventListener("touchstart", touchFn);
            this.ele.addEventListener("touchend", touchFn);
            var startX, startY, endX, endY;
            function touchFn(e){
                e.preventDefault();
                var firstTouch = e.changedTouches[0];
                switch (e.type){
                    case "touchstart":
                        startX = firstTouch.pageX;
                        startY = firstTouch.pageY;
                        break;
                    case "touchend":
                        endX = firstTouch.pageX;
                        endY = firstTouch.pageY;
                        //x方向移动大于y方向的移动,并且x方向的移动大于25个像素,表示在向左侧滑动
                        if (Math.abs(endX - startX) >= Math.abs(endY - startY) && startX - endX >= 25){
                            handler.call(this, e);
                        }
                        break;
                }
            }
        },
        /* 右侧滑动 */
        rightLeft: function (e){
            //TODO: 这里交给自己diy
        }
    }
    //全局$赋值 可以直接调用
    window.$ = window.myMobile = myMobile;
})(window);

页面调用

<!DOCTYPE> 
<html lang="ZH-cn"> 
    <head>
        <meta charset="utf-8" >
        <title>标题</title>
        <meta name="keywords" content="关键字" /> 
        <meta name="description" content="网页描述" />
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />
    <script src="./event.js"></script>
    </head>
    <style>
    </style>
<body>
    <button>点我</button>
    <script>
            $("button").tap(function (e){
                console.log("单击事件")
            })
            $("button").longTag(function (){
                console.log("长按事件");
            })
            $("button").slideLeft(function (e){
                console.log(this);
                this.innerHTML = "左侧滑动了....."
            })    
    </script>
</body>
</html>

FAQ

大家在使用的时候可能会有一些疑问,比如说我左滑事件为什么会触发单击事件?一般实际业务中,不存在这种场景。如果有,某一个元素既有单击事件又有左滑事件,那做一个节流阀就ok了,做一个判断,如果是左滑或者右滑事件就禁止触发单击事件。


目录
相关文章
|
7月前
|
小程序 前端开发 JavaScript
微信小程序框架---视图层&逻辑层&API&事件
微信小程序框架---视图层&逻辑层&API&事件
136 0
|
5月前
|
存储 JavaScript 数据处理
uniapp获取接口数据并渲染至页面中
uniapp获取接口数据并渲染至页面中
105 0
|
5月前
|
小程序
Uniapp 解决组件在官方文档不支持的事件上,接收小程序原生组件事件
Uniapp 解决组件在官方文档不支持的事件上,接收小程序原生组件事件
63 0
|
5月前
|
存储 移动开发 JavaScript
【原生】sd.js帮助您简化繁重的获取数据、存储数据(CRUD)骚操作(吐槽~在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据)
【原生】sd.js帮助您简化繁重的获取数据、存储数据(CRUD)骚操作(吐槽~在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据)
|
6月前
|
小程序 JavaScript API
小程序数据请求API渲染教程
小程序数据请求API渲染教程
131 0
|
6月前
|
存储 API UED
uniapp跨页面传递数据的几种方式
uniapp跨页面传递数据的几种方式
292 0
|
7月前
|
JavaScript 前端开发
“深入理解事件处理器、表单综合案例和组件通信“
“深入理解事件处理器、表单综合案例和组件通信“
22 0
|
9月前
|
JavaScript 小程序
UniApp 小程序封装原生组件(使用与交互详细流程)
UniApp 小程序封装原生组件(使用与交互详细流程)
253 0
antd组件库封装42-样式解决方案分析
antd组件库封装42-样式解决方案分析
88 0
antd组件库封装42-样式解决方案分析