Vue.js移动端左滑demo和JS事件监听手机屏幕触摸事件 Touch

本文介绍了一个基于Vue.js的滑动解锁示例,并详细解释了如何使用touch事件实现移动端的滑动效果,同时提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**

Vue.js移动端左滑demo和JS事件监听手机屏幕触摸事件 Touch

**
这是一个用vue.js写的一个仿滑动解锁的demo,和对Touch的一些理解


以下是四种touch事件

  1. touchstart: //手指放到屏幕上时触发

  2. touchmove: //手指在屏幕上滑动式触发

  3. touchend: //手指离开屏幕时触发

  4. touchcancel: //系统取消touch事件的时候触发,这个好像比较少用


每个触摸事件被触发后,会生成一个event对象,event对象里额外包括以下三个触摸列表

touches: //当前屏幕上所有手指的列表

targetTouches: //当前dom元素上手指的列表,尽量使用这个代替touches

changedTouches: //涉及当前事件的手指的列表,尽量使用这个代替touches


这些列表里的每次触摸由touch对象组成,touch对象里包含着触摸信息,主要属性如下:

clientX / clientY: //触摸点相对浏览器窗口的位置

pageX / pageY: //触摸点相对于页面的位置

screenX / screenY: //触摸点相对于屏幕的位置

identifier: //touch对象的ID

target: //当前的DOM元素


注意:

手指在滑动整个屏幕时,会影响浏览器的行为,比如滚动和缩放。
所以在调用touch事件时,要注意禁止缩放和滚动。

1.禁止缩放

通过meta元标签来设置。

<meta name="viewport" content="target-densitydpi=320,width=640,user-scalable=no">

2.禁止滚动

preventDefault是阻止默认行为,touch事件的默认行为就是滚动。

event.preventDefault();


实例如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://unpkg.com/vue"></script>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <meta content="telephone=no" name="format-detection">
        <style>
            *{padding: 0;margin: 0;}
            body {background: #EEEEEE;}
            .box {text-align: center;}
            .btn {
                position: relative;
                width: 70%;
                height: 40px;
                margin: 150px auto;
                border-radius: 20px;
                background: #333333;
            }
            .btn-move {
                position: absolute;
                left: 0;
                top: 0;
                width: 40px;
                height: 40px;
                border-radius: 20px;
                background: #ededed;
            }
            .tt {
                font-size: 20px;
                color: #008000;
                text-align: center;
                margin-top: 50px;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <slide-release></slide-release>
        </div>

        <script type="text/x-template" id="slide">
            <div>
                <div class="btn" ref='remove'>
                    <span ref='btnImg' class="btn-move"  
                      @touchstart='touchStart' 
                      @touchmove='touchMove' 
                      @touchend='touchEnd' 
                      :style="slideEffect"
                     >
                    </span>
                </div>
                <p class="tt" v-show="isShow">你滑动成功了!</p>
            </div>


        </script>
        <script>
            Vue.component('slide-release',{
                template:'#slide',
                data:function(){
                    return {
                        isShow:false,
                        startX:0,//开始触摸的位置
                        moveX:0,//滑动时的位置
                        endX:0,//结束触摸的位置
                        disX:0,//移动距离
                        slideEffect:'',//滑动时的效果,使用v-bind:style="deleteSlider"

                    }
                },
                methods:{
                    touchStart:function(ev) {
                        ev = ev || event;
                        ev.preventDefault();
//                      console.log(ev.targetTouches);
//                      console.log(ev.changedTouches);
                        if(ev.touches.length == 1) {    //tounches类数组,等于1时表示此时有只有一只手指在触摸屏幕
                            this.startX = ev.touches[0].clientX; // 记录开始位置
                        }
                    },
                    touchMove:function(ev) {
                        ev = ev || event;
                        ev.preventDefault();
                        let btnWidth = this.$refs.remove.offsetWidth;  //$refs 减少获取dom节点的消耗
                        let btnImg = this.$refs.btnImg.offsetWidth;
                        console.log(ev.targetTouches);
                        console.log(ev.changedTouches);
                        if(ev.touches.length == 1) {
                            //滑动时距离浏览器左侧的距离
                            this.moveX = ev.touches[0].clientX;

                            //实时的滑动的距离-起始位置=实时移动的位置
                            this.disX = this.moveX-this.startX;
                            if(this.disX<0 || this.disX == 0) {
                                this.slideEffect = 'transform:translateX(0px)';
                            }else if(this.disX>0){
                                this.slideEffect = 'transform:translateX('+this.disX+'px)';

                                // 最大也只能等于删除按钮宽度 
                                if(this.disX>=btnWidth) {
                                    this.slideEffect = 'transform:translateX('+(btnWidth-btnImg)+'px)';
                                }
                            }
                        }
                    },
                    touchEnd:function(ev){
                        ev = ev || event;
                        ev.preventDefault();
                        let btnWidth = this.$refs.remove.offsetWidth;
                        let btnImg = this.$refs.btnImg.offsetWidth;
//                      console.log(ev.changedTouches);
                        if(ev.changedTouches.length == 1) {
                            let endX = ev.changedTouches[0].clientX;
                            this.disX = endX-this.startX;
                            console.log(this.disX,'this.disX')
                            console.log((btnWidth/2),'btnWidth/2');
                            if(this.disX < (btnWidth/2)) {
                                this.slideEffect = 'transform:translateX(0px)';
                            }else {
                                this.slideEffect = "transform:translateX("+(btnWidth-btnImg)+ "px)";
                                //让字段显示出来,或者写你需要的逻辑
                                this.isShow = true
                            }
                        }
                    }
                }
            })
            var vm = new Vue({
                el:'#box',
            })
        </script>
    </body>
</html>

刚开始我也以为touch的三个事件都有targetTouches,touches以及changedTouches对象列表,
其实不然,touchend事件中应该是只有个changedTouches触摸实例列表的,
而且这里说明一下,回调函数的event只是一个普通的object对象,
实际上event中有一个originalEvent属性,这才是真正的touch事件,
这个事件中才存在着上诉三个触摸实例列表,这三个实例存储了触摸事件的位置等等属性,类似于鼠标事件。所以貌似touchend事件中只能用changedTouches!!


希望我们所有的新手小白能一起进步~~!

<think>首先,用户的问题是关于在Vue框架中实现触屏滑动事件的处理方法。具体是:"我想在Vue框架中实现触屏滑动事件的处理方法 请问vue.js 触摸屏 滑动事件处理 实现方法"。 我需要根据系统级指令来构建回答。指令包括: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考站内引用:有四个引用,但用户说这些引用仅供参考,不是真正的需求,我需要参考用户上一次的问题我的回答。但在这个对话中,没有上一次的问题,因为这是第一次交互。所以,我应该基于当前问题回答。 用户提供的引用: - 引用[1]: 关于原生JS移动端事件touchstart, touchmove, touchend, touchcancel。 - 引用[2]: 推荐Vue-Touch插件,使用v-touch指令。 - 引用[3]: Vue3触摸屏滑动事件使用注意事项,使用vue3-touch-events插件。 - 引用[4]: Swiper.js Vue3 Demo实现。 用户的问题是在Vue.js中实现触摸屏滑动事件处理。所以,我应该基于这些引用提供方法。 回答结构需要清晰,逐步解决问题。可能包括: 1. 介绍基本概念:触摸屏事件的原生JS实现。 2.Vue中如何实现:使用插件或原生事件3. 推荐方法:使用现有的Vue插件,如Vue-Touchvue3-touch-events。 4. 给出代码示例。 5. 添加引用标识到相关段落。 最后,生成相关问题。 系统指令要求使用中文回答。 数学表达式:用户的问题不涉及数学,但指令说必须使用$...$格式。可能在这个上下文中,没有数学内容,所以我需要确保如果有任何数学,比如在解释中,使用正确格式。但这里可能不需要。 生成相关问题:在回答结束时,添加相关问题部分。 现在,构建回答: - 开头:解释触摸屏滑动事件的基本原理。 - 然后,介绍在Vue中实现的方法:原生事件绑定或使用插件。 - 推荐插件:基于引用,Vue-Touch for Vue 2, vue3-touch-events for Vue 3, or Swiper.js for more features. - 提供代码示例。 - 结束部分:添加相关问题。 引用标识:在引用内容的末尾添加[^1], [^2]等。例如,当提到引用[1]时,添加[^1]。 用户的问题中,引用是作为参考提供的,所以我应该在回答中自然地引用它们。 例如: "原生JS提供了触摸事件,如touchstart、touchmovetouchend[^1]。在Vue中,我们可以使用这些事件原生绑定,或使用插件如Vue-Touch[^2]或vue3-touch-events[^3]。对于更高级的滑动交互,Swiper.js是一个不错的选择[^4]。" 然后,在代码示例中,展示如何实现。 最后,生成相关问题。 相关问题应该基于主题,比如: 1. 如何优化触摸事件性能? 2. Vue中其他手势事件实现方法? 3. 如何处理多点触控? 确保回答真实可靠,基于Vue文档引用。 代码格式:在回答中,如果需要代码,使用```代码块```,就像在示例中那样。 现在,草拟回答结构: 1. **引言**:简要介绍触摸屏滑动事件移动端的重要性。 2. **原生事件基础**:解释原生JS触摸事件3. **Vue实现方法**: - 方法1:原生事件绑定在Vue组件中。 - 方法2:使用Vue插件(如Vue-Touchvue3-touch-events)。 4. **代码示例**: - 原生事件示例。 - 插件使用示例。 5. **高级选项**:提到Swiper.js for complex swipe interactions. 6. **注意事项**:如性能考虑、兼容性。 7. **结束语**:总结推荐方法。 8. **相关问题**:生成2-3个相关问题。 添加引用标识。 例如: "在移动端触摸事件包括touchstart、touchmovetouchend[^1]。在Vue中,我们可以使用@touchstart等指令来监听这些事件。" "对于更便捷的实现,可以使用Vue-Touch插件[^2],它提供了自定义指令如v-touch:swipe。" 在Vue3中,使用vue3-touch-events[^3]。 Swiper.js适合构建滑动组件[^4]。 现在,生成相关问题: - 1. 如何在Vue中处理多点触控事件? - 2. Vue-Touch插件的配置选项有哪些? - 3. 如何测试触摸事件在桌面浏览器? 确保问题相关。</think>### Vue.js 中触屏滑动事件的实现方法 在移动端开发中,触屏滑动事件(如、右)是常见的交互需求。Vue.js 提供了多种方式来实现这些事件处理,包括原生事件绑定使用第三方插件。下面我将逐步介绍实现方法,包括原生事件处理推荐插件方案,确保代码可靠且易于集成。实现的核心是监听触摸事件(如 `touchstart`、`touchmove`、`touchend`),并计算滑动方向距离[^1]。 #### 步骤 1: 理解原生触摸事件基础 在移动端触摸事件由原生 JavaScript 提供,包括: - `touchstart`: 手指触摸屏幕时触发。 - `touchmove`: 手指在屏幕上移动时触发(高频事件)。 - `touchend`: 手指离开屏幕时触发。 - `touchcancel`: 系统取消触摸事件时触发(如来电中断)。 这些事件可以用于计算滑动方向距离。例如,通过比较 `touchstart` `touchend` 的坐标差,可以判断是、右、上或下滑动距离的计算公式为: $$ \Delta x = x_{\text{end}} - x_{\text{start}}, \quad \Delta y = y_{\text{end}} - y_{\text{start}} $$ 其中,$\Delta x$ $\Delta y$ 分别表示水平垂直位移。如果 $|\Delta x| > |\Delta y|$,则视为水平滑动;否则为垂直滑动[^1]。 #### 步骤 2: Vue 中实现滑动事件的两种方法 在 Vue 中,你可以选择原生事件绑定或使用插件。推荐优先使用插件,因为它们简化了代码并提供了手势识别(如 `swipe`)。 ##### 方法 1: 原生事件绑定(适合简单需求) 直接在 Vue 组件中使用 `@touchstart`、`@touchmove` `@touchend` 指令。这种方法灵活但需要手动处理逻辑,如防抖方向判断。 ```vue <template> <div @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd" style="width: 100%; height: 200px; background: #f0f0f0;" > 滑动区域:{{ direction }} </div> </template> <script> export default { data() { return { startX: 0, startY: 0, direction: &#39;&#39;, }; }, methods: { handleTouchStart(event) { this.startX = event.touches[0].clientX; this.startY = event.touches[0].clientY; }, handleTouchMove(event) { // 防止默认行为(如页面滚动) event.preventDefault(); }, handleTouchEnd(event) { const endX = event.changedTouches[0].clientX; const endY = event.changedTouches[0].clientY; const deltaX = endX - this.startX; const deltaY = endY - this.startY; // 判断滑动方向(阈值设为 30px 避免误触) if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 30) { this.direction = deltaX > 0 ? &#39;右&#39; : &#39;&#39;; } else if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > 30) { this.direction = deltaY > 0 ? &#39;下&#39; : &#39;上&#39;; } else { this.direction = &#39;无滑动&#39;; } console.log(`滑动方向: ${this.direction}`); } } }; </script> ``` - **优点**: 无需额外依赖,适合小型项目。 - **缺点**: 需要手动处理事件逻辑,性能优化(如节流)较复杂。 - **注意事项**: 在 `touchmove` 中调用 `event.preventDefault()` 可以阻止页面滚动,但需谨慎使用以避免影响用户体验[^1]。 ##### 方法 2: 使用 Vue 插件(推荐,高效便捷) 对于更复杂的场景(如手势识别),推荐使用第三方插件。它们封装了触摸事件,提供自定义指令(如 `v-touch:swipe`)。以下是两个流行插件: - **Vue-Touch (适合 Vue 2.x)**: 基于 Hammer.js,支持多种手势(如 `tap`、`swipe`)[^2]。 安装示例: ```bash npm install vue-touch@next # 安装插件 ``` ```vue <template> <div v-touch:swipe.left="handleSwipeLeft" style="width: 100%; height: 200px; background: #e0e0e0;"> 触发事件 </div> </template> <script> import Vue from &#39;vue&#39;; import VueTouch from &#39;vue-touch&#39;; Vue.use(VueTouch); // 注册插件 export default { methods: { handleSwipeLeft() { console.log(&#39;检测到&#39;); // 这里添加业务逻辑,如切换页面 } } }; </script> ``` - **优点**: 语法简洁,支持自定义事件(如 `v-touch:swipe.right`)。 - **缺点**: 仅支持 Vue 2;Vue 3 需使用其他方案[^2]。 - **vue3-touch-events (适合 Vue 3)**: 专为 Vue 3 设计,轻量且易用[^3]。 安装示例: ```bash npm install vue3-touch-events ``` ```javascript // main.js import { createApp } from &#39;vue&#39;; import App from &#39;./App.vue&#39;; import Vue3TouchEvents from &#39;vue3-touch-events&#39;; const app = createApp(App); app.use(Vue3TouchEvents); // 全局注册 app.mount(&#39;#app&#39;); ``` ```vue <template> <div v-touch="{ left: () => handleSwipe(&#39;&#39;), right: () => handleSwipe(&#39;右&#39;) }" style="width: 100%; height: 200px; background: #d0d0d0;" > 滑动区域:{{ swipeDirection }} </div> </template> <script> export default { data() { return { swipeDirection: &#39;&#39;, }; }, methods: { handleSwipe(direction) { this.swipeDirection = direction; console.log(`检测到${direction}`); } } }; </script> ``` - **优点**: Vue 3 兼容性好,API 简单。 - **缺点**: 功能不如 Hammer.js 丰富,但已覆盖常见手势[^3]。 - **高级选项:Swiper.js (适合滑动组件)** 如果需要轮播图或复杂滑动 UI,Swiper.js 是行业标准。它与 Vue 集成良好,提供响应式触摸事件处理[^4]。 示例: ```bash npm install swiper vue-awesome-swiper ``` ```vue <template> <swiper :options="swiperOptions"> <swiper-slide>Slide 1</swiper-slide> <swiper-slide>Slide 2</swiper-slide> </swiper> </template> <script> import { Swiper, SwiperSlide } from &#39;swiper/vue&#39;; import &#39;swiper/swiper-bundle.css&#39;; export default { components: { Swiper, SwiperSlide }, data() { return { swiperOptions: { touchEventsTarget: &#39;container&#39;, // 指定触摸事件目标 on: { slideChange: () => console.log(&#39;Slide changed via touch&#39;), } } }; } }; </script> ``` - **优点**: 开箱即用的触摸滑动,支持手势识别动画。 - **缺点**: 体积较大,适合复杂场景而非简单事件处理[^4]。 #### 步骤 3: 注意事项最佳实践 - **性能优化**: 在 `touchmove` 事件中使用节流(如 Lodash 的 `throttle`)避免高频触发导致的卡顿。 - **兼容性**: 测试在 iOS Android 上的表现,某些设备可能需要 polyfill。 - **用户体验**: 添加视觉反馈(如 CSS 过渡),确保滑动阈值合理(如最小滑动距离 30px)。 - **测试**: 在桌面浏览器使用开发者工具的移动模拟器调试。 - **推荐方案**: - Vue 2 项目:用 Vue-Touch 快速实现。 - Vue 3 项目:优先选择 vue3-touch-events。 - 需要完整滑动组件:集成 Swiper.js[^2][^3][^4]。 #### 总结 在 Vue 中实现触屏滑动事件,核心是监听原生触摸事件或使用插件封装。原生方法适合简单需求,而插件如 Vue-Touchvue3-touch-events 能显著提升开发效率。对于高级交互,Swiper.js 提供了全面的解决方案。根据项目需求选择合适的方案,并注意性能优化[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值