整体思路,以及代码实现,每一步进行分析,完善,通过移动端的三大事件进行封装,我会将思路写在代码中,这样方便理解!!
开始: action!!!
<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>大玄!!title>
head>
<body>
<script>
function swipe(ele, options) {
// 1.首先将元素绑定 触摸开始事件,并将事件对象传入
ele.addEventlistener('touchstart', function(e) {
});
// 2.将元素绑定 触摸移动事件, 并将事件对象传入
ele.addEventistener('touchmove', function(e) {
});
// 3.将元素绑定 触摸结束事件,并将事件对象传入
ele.addEventlistener('touchend', function() {
});
};
var html = document.documentElement;
script>
body>
html>
不要着急,先将整体思路理一下,通过三大事件进行模拟swipe事件,然后对每一步进行完善!!!
第二步
<title>大玄!!title>
head>
<body>
<script>
function swipt(ele, options) {
// 5.定义全局变量
var startX;
var startY;
var moveX;
var moveY;
// 7.1
var isMove = false;
// 1.首先将元素绑定 触摸开始事件,并将事件对象传入
ele.addEventlistener('touchstart', function(e) {
// 4.在这里记录开始滑动的坐标,这里的变量需要外面进行访问, so 使用全局变量
startX = e.touches[0].pageX;
startY = e.touches[0].pageY;
});
// 2.将元素绑定 触摸移动事件, 并将事件对象传入
ele.addEventistener('touchmove', function(e) {
// 6.开始的坐标记录好了,开始记录移动过程中大的坐标,由于在移动过程中,后面的值会将上一次移动的值进行覆盖,所以拿到最后一次的值就OK了
// 接着定义全局变量
moveX = e.touches[0].pageX;
moveY = e.touches[0].pageY;
// 7.2 如果用户划拉了,将开关重新赋值,
isMove = true;
});
// 3.将元素绑定 触摸结束事件,并将事件对象传入
ele.addEventlistener('touchend', function() {
// 7.怎样才能判断用户开启了触摸移动事件呢? 定义一个开关 相当于flag
if (isMove) {
// 8 .开始的坐标有了,结束的坐标也有了,接下来咱们是不是该判断了,用户到底是水平方向划拉还是垂直向下划拉..
// 8.1 取绝对值
var absX = Math.abs(moveX - startX);
var absY = Math.abs(moveY - startY);
// 9.进行判断如果X轴大于Y轴,拿将是水平方向划拉,否则反之
if (absX > absY) {
console.log('水平方向滑动');
} else {
console.log('垂直方向滑动');
}
}
});
};
var html = document.documentElement;
swipe(html, {
swipeLeft: function() {
alert('向左滑动')
},
swipeRight: function() {
alert('向右滑动')
}
});
script>
body>
好了,大概这个样子就可以了,但是你还会发现一个问题,就是这些方法,是不是用户全部都得传入才可以啊,如果不传的话,就要报错了,所以这里面就会用到默认值,在函数里面咱们进行定义,如果没有传入的话,就使用默认值,要是穿入了的话,就使用用户传入的值.
<title>大玄!!title>
head>
<body>
<script>
function swipt(ele, options) {
// 5.定义全局变量
var startX;
var startY;
var moveX;
var moveY;
// 7.1
var isMove = false;
// 1.首先将元素绑定 触摸开始事件,并将事件对象传入
ele.addEventlistener('touchstart', function(e) {
// 4.在这里记录开始滑动的坐标,这里的变量需要外面进行访问, so 使用全局变量
startX = e.touches[0].pageX;
startY = e.touches[0].pageY;
});
// 2.将元素绑定 触摸移动事件, 并将事件对象传入
ele.addEventistener('touchmove', function(e) {
// 6.开始的坐标记录好了,开始记录移动过程中大的坐标,由于在移动过程中,后面的值会将上一次移动的值进行覆盖,所以拿到最后一次的值就OK了
// 接着定义全局变量
moveX = e.touches[0].pageX;
moveY = e.touches[0].pageY;
// 7.2 如果用户划拉了,将开关重新赋值,
isMove = true;
});
// 3.将元素绑定 触摸结束事件,并将事件对象传入
ele.addEventlistener('touchend', function() {
// 7.怎样才能判断用户开启了触摸移动事件呢? 定义一个开关 相当于flag
if (isMove) {
// 8 .开始的坐标有了,结束的坐标也有了,接下来咱们是不是该判断了,用户到底是水平方向划拉还是垂直向下划拉..
// 8.1 取绝对值
var absX = Math.abs(moveX - startX);
var absY = Math.abs(moveY - startY);
// 9.进行判断如果X轴大于Y轴,拿将是水平方向划拉,否则反之
if (absX > absY) {
// console.log('水平方向滑动');
// 10.由于一个周是两个方向,so 有正向与反向两种说法,接下来进一步进行判断
// 如果移动的距离大于起始距离的话,那就是向右划拉,如果小于的话就是向左划拉
if (moveX - startX > 0) {
// console.log('这是向右滑动');
options.swipeRight();
} else {
// console.log('这是向左滑动');
options.swipeLeft();
}
} else { // 这里判断完了,咱们要的结果不是打印什么,而是要执行什么方法,所以采用对象的方式进行传值
// console.log('垂直方向滑动');
if (moveY - startY > 0) {
// console.log('这是向下滑动');
options.swipeDown();
} else {
// console.log('这是向上滑动');
options.swipeUp();
}
}
}
// 在结束的时候,不管触发没有,都要将开关重新赋值回去
isMove = false;
});
};
var html = document.documentElement;
swipe(html, {
swipeLeft: function() {
alert('向左滑动')
},
swipeRight: function() {
alert('向右滑动')
},
swipeUp: function() {
alert('向上滑动');
},
swipeDown: function() {
{
alert('向下滑动');
}
}
});
script>
将函数进行优化,封装的更好一丢丢
下面的代码将是优化完成之后的样子,虽然不能实现什么大的功能,但是基本的移动端的滑动事件可以实现了!!
<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>大玄!!title>
head>
<body>
<script>
function swipe(ele, options) {
// 5.定义全局变量
var startX;
var startY;
var moveX;
var moveY;
var disX;
var disY;
// 7.1
var isMove = false;
// 12.设置默认值
var defaults = {
swipeRight: function() {},
swipeLeft: function() {},
swipeDown: function() {},
swipeUp: function() {},
drag: function() {}
}
// 13.不传的话,就要报错了,所以这里面就会用到默认值,在函数里面咱们进行定义,如果没有传入的话,就使用默认值,要是穿入了的话,就使用用户传入的值.
// for (var k in defaults) {
// defaults[k] = options[k];
// };
// 上面是一种方法,这里介绍另一种方法对象覆盖的方法
Object.assign(defaults, options);
// 1.首先将元素绑定 触摸开始事件,并将事件对象传入
ele.addEventListener('touchstart', function(e) {
// 4.在这里记录开始滑动的坐标,这里的变量需要外面进行访问, so 使用全局变量
startX = e.touches[0].pageX;
startY = e.touches[0].pageY;
disX = startX - ele.offsetLeft;
disY = startY - ele.offsetTop;
});
// 2.将元素绑定 触摸移动事件, 并将事件对象传入
ele.addEventListener('touchmove', function(e) {
// 6.开始的坐标记录好了,开始记录移动过程中大的坐标,由于在移动过程中,后面的值会将上一次移动的值进行覆盖,所以拿到最后一次的值就OK了
// 接着定义全局变量
moveX = e.touches[0].pageX;
moveY = e.touches[0].pageY;
// 7.2 如果用户划拉了,将开关重新赋值,
isMove = true;
e.info = {
startX: startX,
startY: startY,
disX: disX,
disY: disY
};
// 13.将在touchmove事件发生的时候要做的事情写在函数外面 => drag
defaults.drag.call(ele, e);
});
// 3.将元素绑定 触摸结束事件,并将事件对象传入
ele.addEventListener('touchend', function() {
// 7.怎样才能判断用户开启了触摸移动事件呢? 定义一个开关 相当于flag
if (isMove) {
// 8 .开始的坐标有了,结束的坐标也有了,接下来咱们是不是该判断了,用户到底是水平方向划拉还是垂直向下划拉..
// 8.1 取绝对值
var absX = Math.abs(moveX - startX);
var absY = Math.abs(moveY - startY);
// 9.进行判断如果X轴大于Y轴,拿将是水平方向划拉,否则反之
if (absX > absY) {
// console.log('水平方向滑动');
// 10.由于一个周是两个方向,so 有正向与反向两种说法,接下来进一步进行判断
// 如果移动的距离大于起始距离的话,那就是向右划拉,如果小于的话就是向左划拉
if (moveX - startX > 0) {
// console.log('这是向右滑动');
options.swipeRight();
} else {
// console.log('这是向左滑动');
options.swipeLeft();
}
} else { // 这里判断完了,咱们要的结果不是打印什么,而是要执行什么方法,所以采用对象的方式进行传值
// console.log('垂直方向滑动');
if (moveY - startY > 0) {
// console.log('这是向下滑动');
options.swipeDown();
} else {
// console.log('这是向上滑动');
options.swipeUp();
}
}
}
// 11.在结束的时候,不管触发没有,都要将开关重新赋值回去
isMove = false;
});
};
var html = document.documentElement;
swipe(html, {
swipeLeft: function() {
console.log('向左滑动')
},
swipeRight: function() {
console.log('向右滑动')
},
swipeUp: function() {
console.log('向上滑动');
},
swipeDown: function() {
console.log('向下滑动');
},
drag: function(e) {
console.log('拖拽事件');
// 在拖拽的时候需要获取到移动过程中的 pageX与pageY,由于在外面是获取不到函数内部的属性,所以在函数内部进行对象输出
console.log('开始的X距离是' + e.info.startX);
console.log('开始的Y距离是' + e.info.startY);
console.log('盒子内部的X距离是' + e.info.disX);
console.log('盒子内部的Y距离是' + e.info.disY);
a = e.touches[0].pageX - e.info.disX + 'px';
b = e.touches[0].pageY - e.info.disY + 'px';
console.log(a);
console.log(b);
}
});
script>
body>
html>
在此附上我的QQ: 2489757828 有问题的话可以一同探讨
我的私人博客: 李大玄