vue中touch和click共存的解决方式

在vue开发手机端项目时,我们经常会遇到touch和click共存的情况,比如城市选择页面的字母滑动

touch事件在手机端会触发浏览器滑动,所以应给touch事件添加阻止默认行为touchmove.prevent。注意阻止默认行为事件不要添加在touchstart事件上,会影响到click事件的发生。

touch事件和click事件发生先后顺序:

touchstart,touchmove,touchend,click

补充知识:touchstart与click同时触发

产生冲突的原因

我们可以给某个元素同时绑定 touchstart 和 click 事件,但这将会导致本篇文章解决的问题 – 这两个事件在移动设备上会发生冲突。

由于移动设备能够同时识别 touchstart 和 click 事件,因此当用户点击目标元素时,绑定在目标元素上的 touchstart 事件与 click 事件(约300ms后)会依次被触发,也就是说,我们所绑定的回调函数会被执行两次!。这显然不是我们想要的结果。

解决方案

(1)原生JS

方法一:

使用事件对象中的 preventDefault 方法,preventDefault 方法的作用在于:阻止元素默认事件行为的发生,但有意思的是,当我们在目标元素同时绑定 touchstart 和 click 事件时,在 touchstart 事件回调函数中使用该方法,可以阻止后续 click 事件的发生。

const Button = document.getElementById("targetButton")
Button.addEventListener("touchstart", e => {
 e.preventDefault()
 console.log("touchstart event!")
})

Button.addEventListener("click", e => {
 e.preventDefault()
 console.log("click event!")
})

方法二:

基于功能检测绑定事件

我们可以通过判断浏览器是否支持 touchstart 事件来封装元素的点击事件,这样客户端会根据当前环境判定元素应该绑定的事件类型,代码如下:

const Button = document.getElementById("targetButton")
const clickEvent = (function() {
 if ('ontouchstart' in document.documentElement === true)
 return 'touchstart';
 else
 return 'click';
})();

Button.addEventListener(clickEvent, e => {
 console.log("things happened!")
})

(2) VUE解决方案:

HTML

  <div class="comment-text"
   @touchstart.prevent="gtouchstart(XXX)"
   @touchend.prevent="triggerReply(XXXX)">
   {{ item.content}}
 </div>

JS

 data: function () {
  return {
     Loop: 0
   };
 }
  gtouchstart: function (XXXX) {
    let self = this;
    //执行长按的内容
    self.Loop = setTimeout(function () {
      self.Loop = 0;
      //XXXXXXXXXXXXXXX
    }, 500);
    return false;
  },
  triggerReply: function (XXXX) {
    let self = this;
    clearTimeout(self.Loop);
    //这里click内容
    if (self.Loop !== 0) {
       //XXXXXXXXXXXXXXX
    }
    return false;
  },

添加 touchstart.prevent,组织click事件。

点击事件顺序

点击事件可以分解成多个事件

在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend -->click

以上这篇vue中touch和click共存的解决方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 解决vue组件中click事件失效的问题

    最近使用vue学习开发移动端的项目,使用了bette-scroll插件做滚动.在引入better-scroll的组件中使用@click事件的时候,点击事件失效,v-on:click.v-bind:click.@click.native都不行,试了一下@touchstart是却是可以的,发现better-scroll的配置中没有设置click:true,设置过之后click事件成功. 后来在使用vuex的时候一直报"[vuex] unknown mutation type: changeCity&

  • Vue自定义组件的四种方式示例详解

    四种组件定义方式都存在以下共性(血泪史) 规则: 1.组件只能有一个根标签 2.记住两个词全局和局部 3.组件名称命名中'-小写字母'相当于大写英文字母(hello-com 相当于 helloCom) 而对于在HTML中自定义组件的时候有4种写法,不过也只是殊途同归,都是用template属性对应的只有一个根标签的HTML代码. 1.全局组件 定义方式示例: Vue.component("hello-component",{ props:["message"], t

  • Vue的自定义组件不能使用click方法的解决

    先贴代码 var myButton = Vue.extend({//设置标签 props: ['names', 'item2'],//names为按钮名,item2为数据 template: '<span><span v-for="obj in item2" v-if="obj.name==names" v-html="obj.code"></span></span>' }) Vue.compone

  • VUE解决 v-html不能触发点击事件的问题

    背景:后端返前端html格式的数据,前端用v-html解析渲染,如:<a @click="show(1)"></a>,a标签能成功渲染,但其绑定的事件无法触发. 原因:vue没有将其作为vue的模板解析渲染 解决方案:不用v-html而是component模板编译 上干货: <template> <div class="hello"> <h1> 我是父组件 </h1> <div class

  • vue中touch和click共存的解决方式

    在vue开发手机端项目时,我们经常会遇到touch和click共存的情况,比如城市选择页面的字母滑动 touch事件在手机端会触发浏览器滑动,所以应给touch事件添加阻止默认行为touchmove.prevent.注意阻止默认行为事件不要添加在touchstart事件上,会影响到click事件的发生. touch事件和click事件发生先后顺序: touchstart,touchmove,touchend,click 补充知识:touchstart与click同时触发 产生冲突的原因 我们可以

  • 在vue中使用console.log无效的解决

    webpack开发环境下,在vue中使用console.log无效,一直以为webpack出了问题. 使用window.console.log()就能够顺利在浏览器控制台输出了. 以及 在axios请求的回调中依旧无法输出使用window.console.log()/console.log(),先留坑吧. 补充知识:vue中 :style 与 :class 三元运算符使用 style三元表达式 <p :style="{'color': (checkIndex3==m.txt ? '#3d8

  • Vue中引入svg图标的两种方式

    Vue中引入svg图标的方式 Vue中引入svg图标的方式一 安装 yarn add svg-sprite-loader --dev svg组件 index.vue <!-- svg组件 --> <template> <svg class="svg-icon" :class="svgClass" aria-hidden="true"> <use :xlink:href="iconName&quo

  • webstorm和.vue中es6语法报错的解决方法

    1.webstorm中es6语法报错,解决方法: 打开 Settings => Languages & Frameworks => Javascript 把 Javascript Language version 改为 ECMAScript 6 这样做所有的.js文件中es6不再报错,但是.vue文件中es6语法依然报错. 2. .vue文件中es6语法报错 (1)打开 Settings => File Types 找到 HTML 添加 *.vue 这样vue文件就相当于html

  • 在vue中使用eacharts创建graph关系图方式

    目录 使用eacharts创建graph关系图 vue中关系图组件 1.Graph.vue 2.GraphDemo.vue 使用eacharts创建graph关系图 在最近的工作中遇到了这个问题一开始遇到遇到问题且网上现在的教程不那么详细于是想着自己写一个来记录一下. 首先想使用echarts先下载echarts包命令如下 npm install echarts --save 然后将eacharts引入到项目中,推荐在main.js引入. import * as echarts from 'ec

  • vue中data里面的数据相互使用方式

    目录 data里面的数据相互使用 具体代码如下 data里的数据不能相互引用问题 data里面的数据相互使用 今天在写代码的时候,遇到一个问题,我想使用data里面的一个对象使用data里面的某个数据,附图片: 我想让active的值给params对象里面的topicListType使用,我不想直接在一个方法里面改变这个值(想改的话就直接可以改了,太简单),所以就有了这个想法. 在data里面使用,但是肯定不能写成 this.params.topicListType: this.active,这

  • Vue中使用stylus报错的解决

    目录 一.正常配置stylus流程 二.解决bug 一.正常配置stylus流程 1.安装stylus.stylus-loader依赖(进入项目文件夹下) cnpm install stylus stylus-loader 2.package.json文件配置(手动添加依赖) "devDependencies": { ... "stylus": "^0.54.8", "stylus-loader": "^3.0.2&

  • 详解vue中引入stylus及报错解决方法

    前提条件是已经有了vue项目,如果没有,请先建立,具体方法看这里https://cn.vuejs.org/v2/guide/installation.html 安装stylus 好了,建立好项目后我们来安装stylus npm install stylus stylus-loader --save-dev 这样就安装上了stylus. 接下来就可以使用了,使用方式分两种.一种是在.vue文件的style块中使用,一种是引用.styl文件的形式 在.vue文件的style块中使用 这个很简单,只要

  • vue中this.$refs的坑及解决

    目录 vue this.$refs的坑 以下三点小坑坑 vue的坑 this.refs为空 总结来说 vue this.$refs的坑 在开发中,有时需要使用到this.$refs ,用于操作真实的DOM节点. 说一说我在使用的时候,在开发时碰到了一个小需求,需要子组件向父组件传参,而且是不需要通过事件传递的,一开始使用this.$emit()来写的,但是一直没有接受到参数,于是放弃了使用this.$emit()的使用. 于是,使用了在父组件中调用子组件的方法,来获取传递的参数.但是还是没有获取

  • vue文本识别"\n"换行问题的解决方式

    目录 一.通过 css属性 实现 二.使用v-html实现 三.<pre>标签 附实践模块,温馨提示 基于vant改造 总结 在 vue 项目,有时请求返回的数据 中会有含有 \n 的字符串,如果直接渲染的话无法实现换行. 一.通过 css属性 实现 设置 white-space: pre-wrap;  代码如下: <div style="white-space: pre-wrap;">{{含有\n的字符串}}</div> 扩展: white-spa

随机推荐