前端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元件其實就是一個圖檔自适應的元件。 該元件内類容在上篇文章有過描述
v-if="config.buttons.length>0">
<div class="flex" ref="ddBanner" style="transform: translateX(0px);"
:style="{'width':7.5 * getBtsGroup(config.buttons).length + 'rem'}">
<div v-for="(buttonList,chunkBtnKey) in getBtsGroup(config.buttons)" :key="chunkBtnKey">
<ul class="flex-wrap flex w-750" :class="config.className">
<li class="w20 t-c pad-b-10"
v-for="(item,key) in buttonList"
:key="key"
:class="item.parentClass"
@click.stop="handle(item)"
>
<div
:class="item.class"
:style="item.style"
>
<dd-img v-if="item.src" class="mar-a mar-b-10" :src="item.src" :width="0.85" :height="0.85"/>
<i v-if="item.icon" class="iconfont" :class="item.icon"></i>
<div v-else class="bg-e-i hei100"></div>
</div>
<h3 :class="{'col-t':item.active}">{{item.name}}</h3>
</li>
</ul>
</div>
</div>
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;
.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版權聲明:本文為部落客原創文章,轉載請附上博文連結!