解决VUE自定义拖拽指令时 onmouseup 与 click事件冲突问题

功能描述:

如图,右侧悬浮菜单按钮,只支持上下方向拖动,点击时展开或关闭菜单。

BUG说明:

鼠标上下方向拖拽,如果松开时鼠标位于悬浮按钮上会默认执行click事件,经验证,click事件与mouse事件的执行顺序为onmousedown =》onmouseup =》onclick,意味着在click事件执行时会与与其相关的mouse事件冲突。

解决方案:

因为click事件执行时间短,所以利用鼠标拖动的时间差作为标志,在拖拽事件中计算鼠标从onmousedown 到onmouseup 所用的时间差,与200ms作比较,作为全局变量。由于vue的directives自定义指令中无法使用this,所以个人采用给元素设置属性的方式来解决全局变量的存储问题。

1、自定义上下拖拽指令

说明:指令中没有this关键字,指令中通过el可以直接拿到指令绑定的元素;

  directives: {
   drag: {
    // 指令的定义
    bind: function (el) {
     let odiv = el; //获取当前元素
     let firstTime='',lastTime='';
     odiv.onmousedown = (e) => {
      document.getElementById('dragbtn').setAttribute('data-flag',false)
      firstTime = new Date().getTime();
      // 算出鼠标相对元素的位置
      let disY = e.clientY - odiv.offsetTop;
      document.onmousemove = (e) => {
       // 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
       let top = e.clientY - disY;
       // 页面范围内移动元素
       if (top > 0 && top < document.body.clientHeight - 48) {
        odiv.style.top = top + 'px';
       }
      };
      document.onmouseup = (e) => {
        document.onmousemove = null;
        document.onmouseup = null;
        // onmouseup 时的时间,并计算差值
        lastTime = new Date().getTime();
        if( (lastTime - firstTime) < 200){
         document.getElementById('dragbtn').setAttribute('data-flag',true)
        }
      };
     };
    }
   }
  },

2、悬浮菜单点击事件中进行验证。

click(e) {
 // 验证是否为点击事件,是则继续执行click事件,否则不执行
    let isClick = document.getElementById('dragbtn').getAttribute('data-flag');
    if(isClick !== 'true') {
     return false
    }
    if (!localStorage.settings) {
     return this.$message.error('请选择必填项并保存');
    }
    if (this.right === -300) {
     this.right = 0;
     this.isMask = true;
    } else {
     this.right = -300;
     this.isMask = false;
    }
   },

补充知识:vue 子组件 created 方法不执行问题

近期做了一个项目 里面有一个树形菜单,将数据写在 js (死数据)中,所有的东西都能够正常执行(i 标签,子节点,父节点),但是当在请求接口文件或者请求后台数据的时候,发现引入的子组件的created方法不执行,但是点击父级菜单展开时还是能够触发,后来发现 是生命周期的问题,仔细查看一下,后来解决!

解决方法如下:

用watch 检测一下data的数据变化,created方法既然在点击的时候执行,所以也必须保留,好啦,就这样!

以上这篇解决VUE自定义拖拽指令时 onmouseup 与 click事件冲突问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 解决vue cli4升级sass-loader(v8)后报错问题

    sass-loader报错: Module build failed (from ./node_modules/sass-loader/dist/cjs.js): ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schem a.  - options has an unknown propert

  • vue cli3.0打包上线静态资源找不到路径的解决操作

    项目中遇到打包之后静态资源路径找不到,报如下错误: 解决方法是: 在项目的根目录下创建vue.config,js文件,在里面配置静态资源的路径,publicPath是配置静态资源路径的属性,vue.config,js文件的代码如下: module.exports = { publicPath: './' } 补充知识:vue-cli3 npm run build 打包后静态资源的配置 vue.config.js的配置 vue.config.js配置如下: const path = require

  • vue-cli打包后本地运行dist文件中的index.html操作

    使用npm run build生成dist文件夹中的文件是你需要上传到服务器上的文件, 直接打开index.html会直接报错 可以尝试用express搭建一个服务器,做法如下: 1.在dist根目录下新建server.js文件: 2.代码如下: var express = require('express'); var app = express(); const hostname = 'localhost'; const port = 3000; app.use(express.static

  • Vue-cli assets SubDirectory及PublicPath区别详解

    近期在参与用vue+ springBoot前后端不分离项目,遇到了前端打包后dist文件放到后台无法运行报404错误,static下的资源都访问不了问题. 问题1:我们知道前后端不分离项目,一些静态图片.页面直接放在resource/static下,由于前后台分开开发,前端进行了跨域处理,dist文件放到后台就相当于本地静态资源,所以不需要跨域处理,可以将引入跨域的路径baseURL置空 const service = axios.create({ //baseURL: '/appstore',

  • 解决vue的touchStart事件及click事件冲突问题

    一 .问题: 今天遇到这样问题,给某个元素同时绑定touchStart及click事件后,若在移动设备上,当你点击时,会依次出发这两个事件.因为移动端设备上的click事件触发是会延迟300ms,所以touchStart事件会先触发后再触发click事件.这样导致每次都要执行两次,这样毫无意义.这里提醒下,PC是无法识别touch相关事件 二.解决方式 (1)preventDefault方法 通过使用preventDefault方法(阻止元素默认事件行为的发生)来解决.在touchstart中添

  • 解决vuecli3中img src 的引入问题

    最近公司要做一个在线ps 的项目 但是后台没写完, 我在用本地图片上传预览的时候 发现图片不能显示, 解决的办法 是 //页面的结构 <div class="workspace" > <img :src='img'> </div> export default { data() { return { img:require('../../assets/fapiao.jpeg'), //这里只能使用require的方式去使用 如果img 是数组, 就用

  • vue-cli3 引入 font-awesome的操作

    在 package.json 添加 "font-awesome": "^4.7.0" 执行 npm install 在 main.js 引入 // font import "font-awesome/css/font-awesome.min.css" 补充知识:在Vue2.0中引入font-awesome,并在Element-ui中正确显示font-awesome的icon 如下所示: npm install font-awesome --sav

  • 在vue-cli3中使用axios获取本地json操作

    在vue-cli3中,公共文件夹由static变成了public 先把要访问的json放到public文件夹下 使用axios的get方法获取,不能用post,不然会报404 axios.get(`./china-main-city/100000.json`) .then((data) => { console.log(data) }) 补充知识:两个不同的路由,引入相同的组件 从不同的按钮进入到详情页,两个不同的路由,相同的组件 主要是从不同按钮进入不同路由的页面,内容一致,但是title不一

  • 解决VUE自定义拖拽指令时 onmouseup 与 click事件冲突问题

    功能描述: 如图,右侧悬浮菜单按钮,只支持上下方向拖动,点击时展开或关闭菜单. BUG说明: 鼠标上下方向拖拽,如果松开时鼠标位于悬浮按钮上会默认执行click事件,经验证,click事件与mouse事件的执行顺序为onmousedown =>onmouseup =>onclick,意味着在click事件执行时会与与其相关的mouse事件冲突. 解决方案: 因为click事件执行时间短,所以利用鼠标拖动的时间差作为标志,在拖拽事件中计算鼠标从onmousedown 到onmouseup 所用的

  • 解决vue自定义指令导致的内存泄漏问题

    vue的自定义指令是一个比较容易引起内存泄漏的地方,原因就在于指令通常给元素绑定了事件,但是如果忘记了解绑,就会产生内存泄漏的问题. 看下面代码: directives: { scroll: { inserted (el, cb) { // 不是元素节点 || 未设置回调函数 if (el.nodeType !== 1 || !cb) return let direct = 'down' let rollHeight = 0 let getScrollEventTarget = (target)

  • 基于Vue实现拖拽功能

    本文实例为大家分享了Vue实现拖拽功能的具体代码,供大家参考,具体内容如下 效果图: HTML代码: <div id="box"> 位置 <br>x:{{val.x}} <br>y:{{val.y}} <div v-drag="greet" id="drag" :style="style"> //注意这里要通过指令绑定函数将当前元素的位置数据传出来 </div> &l

  • 基于Vue实现拖拽效果

    效果图 demo1.gif 分清clientY pageY screenY layerY offsetY的区别 在我们想要做出拖拽这个效果的时候,我们需要分清这几个属性的区别,这几个属性都是计算鼠标点击的偏移值,我们需要对其进行了解才可以继续实现我们的拖拽效果 clientY 指的是距离可视页面左上角的距离 pageY 指的是距离可视页面左上角的距离(不受页面滚动影响) screenY 指的是距离屏幕左上角的距离 layerY 指的是找到它或它父级元素中最近具有定位的左上角距离 offsetY

  • Vue实现拖拽穿梭框功能四种方式实例详解

    目录 一.使用原生js实现拖拽 二.VUe使用js实现拖拽穿梭框 三.Vue 拖拽组件 vuedraggable 四.Awe-dnd指令封装 一.使用原生js实现拖拽 <html lang="en"> <head> <meta charset="UTF-8" /> <title>Lazyload</title> <style> .drag { background-color: skyblue;

  • Vue 可拖拽组件Vue Smooth DnD的使用详解

    目录 简介和 Demo 展示 API: Container 属性 生命周期 回调 事件 API: Draggable 实战 简介和 Demo 展示 最近需要有个拖拽列表的需求,发现一个简单好用的 Vue 可拖拽组件.安利一下~ Vue Smooth DnD 是一个快速.轻量级的拖放.可排序的 Vue.js 库,封装了 smooth-dnd 库. Vue Smooth DnD 主要包含了两个组件,Container 和 Draggable,Container 包含可拖动的元素或组件,它的每一个子元

  • vue实现拖拽的简单案例 不超出可视区域

    本文实例为大家分享了vue实现拖拽x效果的具体代码,供大家参考,具体内容如下 实现拖拽之前,先了解几个小常识: 这两种获取鼠标坐标的方法,区别在于基于的对象不同: pageX和pageY获取的是鼠标指针距离文档(HTML)的左上角距离,不会随着滚动条滚动而改变: clientX和clientY获取的是鼠标指针距离可视窗口(不包括上面的地址栏和滑动条)的距离,会随着滚动条滚动而改变: 1.clientX : 是用来获取鼠标点击的位置距离 当前窗口 左边的距离 2.clientY: 是用来获取鼠标点

  • vue实现拖拽进度条

    本文实例为大家分享了vue实现拖拽进度条的具体代码,供大家参考,具体内容如下 组件代码: <template> <div> <div class="slider" ref="slider"> <div class="process" :style="{ width }"></div> <div class="thunk" ref="

  • vue实现拖拽或点击上传图片

    本文实例为大家分享了vue实现拖拽或点击上传图片的具体代码,供大家参考,具体内容如下 一.预览图 二.实现 点击上传思路:将input的type设置为"file"类型即可上传文件.隐藏该input框,同时点击按钮时,调取该input的点击上传功能.剩下的就是css优化页面了. 拖拽上传思路:通过给拖拽框dropbox绑定拖拽事件,当组件销毁时解绑事件.在拖拽结束,通过event.dataTransfer.files获取上传的文件信息.然后在对文件进行上传服务器操作. 接下来请允许我简单

  • vue使用拖拽方式创建结构树

    本文实例为大家分享了vue使用拖拽方式创建结构树的具体代码,供大家参考,具体内容如下 在页面中拖拽虚线框中的节点,创建向右的结构树,如下图 记录实现思路: vueTree.vue <template> <div class="container"> <div class="node-container"> <div v-for="(item, index) in nodeList" :key="

随机推荐