前言
H5
提供了touch
事件来进行移动端的交互,但touch
事件在pc
上是无效的
pc
上可以使用mouse
事件实现同样的效果,可以在使用的时候判断是否为移动端来切换对应的事件,这样写的坏处不用多说 不优雅也不好用
vue
提供了许多指令来便于我们的开发 -比如v-for
v-if
v-bind
···等等
同时也提供了自定义指令 directives
来供我们实现我们所想要的
通过指令我们可以在元素渲染完成时给元素添加触摸事件,在指令内部完成事件的判断和绑定
实现过程
定义一个局部指令move
,bind
为渲染完成后的钩子函数el
为绑定的元素 binding
可以理解为传入的参数
<!--在模版中使用注意要加上 v- -->
<div class="container" v-move="{start,move,end}"></div>
export default {
directives: {
move: {
bind: (el, binding) => {
/**
* 判断是PC端还是移动端
* 通过不同的设备定义不同的事件名
*/
const isMobile =
navigator.userAgent.match(
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
) !== null
const [start, move, end] = isMobile
? ['touchstart', 'touchmove', 'touchend']
: ['mousedown', 'mousemove', 'mouseup']
/**
* 开始触摸
* 执行触摸回调函数
* 监听滑动事件
* 监听触摸结束事件
* 监听阻止移动端屏幕移动事件
*/
const startFun = e => {
binding.value.start(e)
el.addEventListener(move, moveFun)
el.addEventListener(end, endFun)
window.addEventListener('touchmove', prevent, {
passive: false
})
}
/**
* 开始滑动
* 执行滑动回调函数
*/
const moveFun = e => {
binding.value.move(e)
}
/**
* 结束触摸
* 执行结束触摸回调函数
* 销毁滑动事件
* 销毁结束触摸事件
* 销毁阻止移动屏幕事件
*/
const endFun = e => {
binding.value.end(e)
el.removeEventListener(move, moveFun)
el.removeEventListener(end, endFun)
window.removeEventListener('touchmove', prevent)
}
/**
* 阻止移动端屏幕移动
*/
const prevent = e => {
e.preventDefault()
}
/**
* 监听触摸事件
*/
el.addEventListener(start, startFun)
}
}
},
methods: {
/**
* 事件的回调 在这里执行你的代码
*/
start: function(e) {
console.log(e)
},
move: function(e) {
console.log(e)
},
end: function(e) {
console.log(e)
}
}
}
注意事项
- 在移动端可能会有触摸移动时同时触发屏幕的移动所以用到了阻止移动屏幕的事件
- 为了性能优化,只在开始时监听开始触摸事件,然后开始触摸时再监听其他事件,最后再结束触摸时销毁这些事件
- 自定义指令中无法访问到
this
所以业务逻辑写在回调函数中比较合适
❝不断成长中,且行且珍惜
❞