介绍一下怎么去封装移动端的轻敲事件,也就是pc端的点击事件
- 为什么封装 :
- 首先为什么封装轻敲事件
- 因为在移动端click事件会有300ms 的延迟,用户体验不好,
- 所以我们根据移动端的三大时间类封装一个tap(统称)事件
- 需求 :
- 在tap事件发生的时候,不能触发touchmove 事件
- touchend发生的时间 — toouchstart发生的时间 < 150ms
- 移动端的轻敲事件 :
- @param {Object} el 发生事件的元素
- @param {Function} fn 事件处理函数
代码实现 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <script>
function tap(ele, fn) {
var startTime; var flag = false;
ele.addEventListener('touchstart', function() { startTime = new Date().getTime(); console.log(startTime); });
ele.addEventListener('touchmove', function() { flag = true; });
ele.addEventListener('touchend', function() { var endTime = new Date().getTime(); if (flag == false && endTime - startTime < 150) { fn(); } })
}
var html = document.documentElement; tap(html, function(e) { console.log(e); console.log(this); }); </script>
|
上面封装好了,但是有很多细节问题
- 当调用一个函数的时候 如果有形参 没有实参 形参的值为undefined , 如果是undefined的时候是不是就会报错,所以呢? 进行判断
- 注意观察这里的代码与上面的有什么不同
1 2 3 4 5 6 7 8 9
| ele.addEventListener('touchend', function() { var endTime = new Date().getTime(); if (flag == false && endTime - startTime < 150) { fn && fn(); } })
|
还有一个问题,就是节点的问题,js中最常见的三个节点 : 文本节点,元素节点,属性节点
所以~~还得进行判断,一步到位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head>
<body> <script> // 1. 首先为什么封装轻敲事件 // 因为在移动端click事件会有300ms 的延迟,用户体验不好, // 所以我们根据移动端的三大时间类封装一个tap(统称)事件
// 2. 需求需求 // 在tap事件发生的时候,不能触发touchmove 事件 // touchend发生的时间 --- toouchstart发生的时间 < 150ms
function tap(ele, fn) { // 如果el身上有nodeType属性 并且属性值为1的话 if (ele.nodeType && ele.nodeType == 1) { var startTime; var flag = false;
// 在轻敲事件开始的时候记录一下时间 由于后面也要使用,所以使用全局变量 ele.addEventListener('touchstart', function() { // 将获取的时间转化为时间戳 startTime = new Date().getTime(); console.log(startTime); // 1533460365267 });
// 在tap事件发生的时候,不能触发touchmove 事件,这该怎么办呢? // 知道 flag 吗? 来一个开关 ele.addEventListener('touchmove', function() { // 如果进入这里面的话,将开关重新赋值 flag = true; });
// 当手指与屏幕离开的时候 // 这里的 e 是浏览器传进来的事件对象, ele.addEventListener('touchend', function(e) { // 记录结束的时间 var endTime = new Date().getTime(); // 怎样才能出发轻敲事件呢? 是不是得使 tap 的条件成立 if (flag == false && endTime - startTime < 150) { // 因为是自己调用的自己,没有事件对象,那该怎么办呢?谁有事件对象? touchend 有,手指离开那个元素,这就是事件对象 // 这里是函数调用 , 所以这里的 e 是实参 // 还需要是函数调用的时候,将这个this指向这个事件对象 fn && fn.call(ele, e); } })
} else { // 进行一个警告 console.warn('轻敲事件的第一个参数必须是元素对象类型'); }
}
var html = document.documentElement;
// 注意这里的函数只是一个普通函数,没有事件对象,如果我们信息网有一个事件对象,哪该怎么办呢? // 是不是应该在调用的时候传进来呢! 这里是形参 tap(html, function(e) { console.log(e); console.log(this); }); </script> </body>
</html>
|
好了,tap事件就封装好了.好好回顾一下!!!