前端JS H5 touch事件封装,更加高效的开发移动端 - 戴向天
大家好!我叫戴向天。今天我给大家分享一个我自己封装的H5 touch事件的封装。
该方法的使用特别的简单,废话不多说。先上代码 ↓↓↓↓↓
/* 给元素绑定事件 /
function touch({dom, start, move, end, stop = true, change}) {
const f = {
data: {},
start(e) { //手指触碰的屏幕就会触发(一次)
stop && e.preventDefault() //阻止冒泡,当stop为false的时候就运行冒泡,默认为true
f.data = { //储存的是一些数据
...f.data, //扩展运算,将之前的数据进行合并
x: e.touches[0].pageX, //手指开始的横向位置
y: e.touches[0].pageY, //手指开始的纵向位置
ex: 0, //手指结束的横向位置
ey: 0, //手指结束的纵向位置
time: new Date().getTime(), //手指的开始时间
}
start && start(f.data) //执行自定义的 start 方法
},
move(e) { //多次
stop && e.preventDefault() //阻止冒泡,当stop为false的时候就运行冒泡,默认为true
f.data = { //储存的是一些数据
...f.data, //扩展运算,将之前的数据进行合并
ex: e.touches[0].pageX, //手指结束的横向位置
ey: e.touches[0].pageY, //手指结束的纵向位置
}
move && move({ //执行自定义的 move方法,并且把得到的数据进行返回
x: e.touches[0].pageX,
y: e.touches[0].pageY,
dx: f.data.ex - f.data.x,
dy: f.data.ey - f.data.y
})
},
end(e) { //手指离开屏幕就会触发(一次)
stop && e.preventDefault() //阻止冒泡,当stop为false的时候就运行冒泡,默认为true
let time = new Date().getTime() //手指离开的时间
end && end({ //执行自定义的 end 方法,并且把得到的数据进行返回
time, //当前时间
startTime: f.data.time, //手指的开始时间
dt: time - f.data.time, //手指在屏幕逗留的时间差 ms
dy: (f.data.ey || f.data.y) - f.data.y, //手指在屏幕上的纵向的移动距离
dx: (f.data.ex || f.data.x) - f.data.x //手指在屏幕上的横向的移动距离
})
// ↓ 下面的就是执行判断手指移动的方向,当达到条件,就会执行change事件,
// change 返回的参数
// direction: left | right | up | down | origin
if (new Date().getTime() - f.data.time < 300) { // 手指开屏幕上的时间很短
if (Math.abs(f.data.ex - f.data.x) > 20 && Math.abs(f.data.ex - f.data.x) > Math.abs(f.data.ey - f.data.y)) {
if (change) {
if (f.data.ex > f.data.x) {
change({
direction: 'right'
})
} else if (f.data.ex < f.data.x) {
change({
direction: 'left'
})
}
}
} else if (Math.abs(f.data.ey - f.data.y) > 20 && Math.abs(f.data.ex - f.data.x) < Math.abs(f.data.ey - f.data.y)) {
if (change) {
if (f.data.ey > f.data.y) {
change({
direction: 'down'
})
} else if (f.data.ey < f.data.y) {
change({
direction: 'up'
})
}
}
} else {
change && change({
direction: 'origin'
})
}
} else if (Math.abs(f.data.ey - f.data.y) >= 50) {
if (change) {
if (f.data.ey > f.data.y) {
change({
direction: 'down'
})
} else if (f.data.ey < f.data.y) {
change({
direction: 'up'
})
}
}
} else if (Math.abs(f.data.ex - f.data.x) >= 50) {
if (change) {
if (f.data.ex > f.data.x) {
change({
direction: 'right'
})
} else if (f.data.ex < f.data.x) {
change({
direction: 'left'
})
}
}
} else {
change && change({
direction: 'origin'
})
}
}
}
// 这里是防止dom元素绑定事件异常,导致整体页面无法正常往下执行
try {
dom.removeEventListener('touchstart', f.start)
dom.addEventListener('touchstart', f.start)
dom.removeEventListener('touchmove', f.move)
dom.addEventListener('touchmove', f.move)
dom.removeEventListener('touchend', f.end)
dom.addEventListener('touchend', f.end)
} catch (e) {
console.error('给dom元素绑定事件的时候出现了错误', e)
}
}
下面我写了一个案例的vue文件 按钮组的组件
里面的style代码是我在我写的公共样式里面进行提取出来的。
dd-img组件其实就是一个图片自适应的组件。 该组件内类容在上篇文章有过描述
export default {
props: {
config: {
type: Object,
default: Object
},
deliver: {
type: Boolean,
default: false,
},
},
data () {
return {
width: 0,
len: 0,
key: 0,
touchData: {
index: 0,
},
}
},
methods: {
getBtsGroup (bts) {
let group = [],
itemGroup = []
bts.forEach((item, i) => {
if (i % 10) {
itemGroup.push(item)
} else {
itemGroup = []
itemGroup.push(item)
group.push(itemGroup)
}
})
return group
},
handle (item) {
console.log(item)
}
},
created () {
const that = this
that.len = that.getBtsGroup(that.config.buttons).length
that.len > 1 && setTimeout(() => {
const ddBanner = that.$refs.ddBanner
that.width = that.len * that.$refs.ddBanner.clientWidth
ddBanner.style.width = that.width + 'px'
this.touch({
dom: ddBanner,
start ({x, y, time}) {
that.touchData.x = x
that.touchData.y = y
that.touchData.time = time
let tf = ddBanner.style.transform
that.touchData.tf = Number(tf.split('(')[1].split('px')[0])
},
move ({x, y}) {
that.touchData.ex = x
that.touchData.ey = y
ddBanner.style.transitionDuration = '0ms'
ddBanner.style.transform = `translateX(${that.touchData.ex - that.touchData.x + that.touchData.tf}px)`
},
change ({direction}) {
switch (direction) {
case 'left':
that.touchData.index > -(that.len - 1) && that.touchData.index--
break
case 'right':
Math.abs(that.touchData.index) > 0 && that.touchData.index++
break
case 'up':
break
case 'down':
break
case 'origin':
break
}
that.key = Math.abs(that.touchData.index)
ddBanner.style.transitionDuration = `500ms`
ddBanner.style.transform = `translateX(${ddBanner.parentNode.clientWidth * that.touchData.index}px)`
}
})
}, 10)
}
}
.fon-b {
font-size: 28px;
}
.pad-t {
padding-top: 30px;
}
.pad-b-10 {
padding-bottom: 10px;
}
.over-h {
overflow: hidden;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex {
display: flex;
}
.w-750 {
width: 750px;
}
.w20 {
width: 20%;
}
.t-c {
text-align: center;
}
.pad-b-10 {
padding-bottom: 10px;
}
.mar-a {
margin: 0 auto;
}
.mar-b-10 {
margin-bottom: 10px;
}
.bg-e-i {
background-color: #eee !important;
}
该组件的使用方法
export default{
data(){
return {
buttonGroupConfig: {
buttons: [
{
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}, {
src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
name: '女生'
}
],
},
}
}
}
由于不知道怎么上传屏幕录制并生成GIF图。具体的效果没能展示。
作者:戴向天
来源:CSDN
原文:https://blog.csdn.net/weixin_41088946/article/details/90764437
版权声明:本文为博主原创文章,转载请附上博文链接!