Vue 实现一个简单的鼠标拖拽滚动效果插件


Posted in Vue.js onDecember 10, 2020

最近开源了一个 Vue 组件,还不够完善,欢迎大家来一起完善它,也希望大家能给个 star 支持一下,谢谢各位了。

github 地址:github.com/qq449245884…

最近在做一个新的项目,有个需要是这样的:

Vue 实现一个简单的鼠标拖拽滚动效果插件

简单描述一下,就是鼠标拖动页面,整个页面会随着的鼠标的拖拽而移动,如果页面有内容,里面的内容也需要跟着拖动的外层整体移到。

一开始没啥思路,所以就发了个朋友圈,得到的答案挺多的,主要还是用拖拽之类的,但这个拖拽只是单个元素的拖动,我想要的整个视图的拖动。

这里线索又断了。

于是又回到飞书有类似功能的页面,然后仔细检查一下它页面的 DOM 结构,如下所示:

Vue 实现一个简单的鼠标拖拽滚动效果插件

发现有这一层,它把页面设置的很宽,很高,为了隐藏滚动条,所以设置overflow: hidden;,看了这一设置,突然灵光一现,难道它是用拖拽来触发滚动条的滚动,在细想,哇靠,这思路可行的,NB。

准备上手试试

创建一个 vue 项目,这个就不细说的,我已经把原码发布到 github 上了,有兴趣自己看看:

https://github.com/qq449245884/vue-drag-scroll

首先给外层加个大大的宽和高:

<div class="vue-drag-scroll-wrapper" :style="zoomStye">
 // 这里省略一些不太重要的代码
</div>

<script>
export default {
 name: 'VueDragScroll',
 props: {
  msg: String
 },
 data () {
  return {
   scale: 100
  }
 },
 computed: {
  zoomStye () {
   const INIT_WIDTH = 2208
   const INIT_HEIGHT = 1206
   const width = INIT_WIDTH * (1 + (100 - this.scale)/100)
   const height = INIT_HEIGHT * (1 + (100 - this.scale)/100)
   console.log(width)
   console.log(height)
   return {
    width: `${width}px`,
    height: `${height}px`,
    transform: `scale(${this.scale/100})`
   }
  }
 }
}
</script>

这里设置了一个计算属性 zoomStye,主要使用就是给外层加一个在的宽,和高,这里我还设置了一个缩放比较,为了是能放大缩小页面,下面讲。运行效果:

Vue 实现一个简单的鼠标拖拽滚动效果插件

接着,我们需要监听鼠标的拖拽来触发滚动条效果,因为需要对 dom 的操作,所以这里把拖拽处理逻辑用 vue 指令封装起来,这样后面有需要,只要使用该指令即可。

注意:在 vue 中如果需要对 dom 进行多次操作,最好是把它封装在指令中。

指令代码如下:

import Vue from 'vue'

Vue.directive('dragscroll', function (el) {
 el.onmousedown = function (ev) {
  console.log(el)
  const disX = ev.clientX
  const disY = ev.clientY
  const originalScrollLeft = el.scrollLeft
  const originalScrollTop = el.scrollTop
  const originalScrollBehavior = el.style['scroll-behavior']
  const originalPointerEvents = el.style['pointer-events']
  // auto: 默认值,表示滚动框立即滚动到指定位置。
  el.style['scroll-behavior'] = 'auto'
  el.style['cursor'] = 'grabbing'
  // 鼠标移动事件是监听的整个document,这样可以使鼠标能够在元素外部移动的时候也能实现拖动
  document.onmousemove = function (ev) {
   ev.preventDefault()
   // 计算拖拽的偏移距离
   const distanceX = ev.clientX - disX
   const distanceY = ev.clientY - disY

   el.scrollTo(originalScrollLeft - distanceX, originalScrollTop - distanceY)
   console.log(originalScrollLeft - distanceX, originalScrollTop - distanceY)
   // 在鼠标拖动的时候将点击事件屏蔽掉
   el.style['pointer-events'] = 'none'
   document.body.style['cursor'] = 'grabbing'
  }
  document.onmouseup = function () {
   document.onmousemove = null
   document.onmouseup = null
   el.style['scroll-behavior'] = originalScrollBehavior
   el.style['pointer-events'] = originalPointerEvents
   el.style['cursor'] = 'grab'
  }
 }
})

这里的主要思路就是利用 el.scrollTo 来触发滚动条的移到。

有了 dragscroll 指令,我们来使用一下,首先我们需要在增加一层外层:

<div v-dragscroll class="vue-drag-scroll-out-wrapper">
 <div class="vue-drag-scroll-wrapper" :style="zoomStye">
  // 这里省略一些不太重要的代码
 </div>
</div>

<style scoped>
.vue-drag-scroll-out-wrapper{
  overflow-x: hidden;
  width: 100%;
  height: 100%;
  cursor: grab;
  position: absolute;
  top:0;
  left: 0;
  &::-webkit-scrollbar { width: 0 !important } // 隐藏垂直方向的滚动条
}
</style>

这里需要注意的在 .vue-drag-scroll-out-wrapper 要设置 overflow 值,否则无法滚动(测试出来的)。

这样拖拽效果就出来啦:

Vue 实现一个简单的鼠标拖拽滚动效果插件

增加缩放

这里,我们增加一个视图的放大和缩小,所以增加两个按钮:

<div class="tolbox-zoom-wrapper">
 <div class="zoom-inner">
 <span class="iconfont iconsuoxiao"
  :class="{'disabled': scale === 25}" style="font-size:22px"
  @click="handleReduce"
 />
 <span class="iconfont iconfangda"
  :class="{'disabled': scale === 100}"
  @click="handleEnlarge" 
 />
 <div class="scale-text">{{scale}}%</div>
 </div>
</div>

效果:

Vue 实现一个简单的鼠标拖拽滚动效果插件

这里的放大和缩小的逻辑就是通过我们增加减少 scale 来实现

handleReduce () {
 if (this.scale === 25) return
 this.scale -= 25
},
handleEnlarge () {
 if (this.scale === 100) return
 this.scale += 25
}

缩放比例的关系就是开关给出的代码:

const INIT_WIDTH = 2208
const INIT_HEIGHT = 1206
const width = INIT_WIDTH * (1 + (100 - this.scale)/100)
const height = INIT_HEIGHT * (1 + (100 - this.scale)/100)

这个比例是我自己定的,比如现在减少到 75% ,那么最外层的高和宽就要对应的增加原来的 25%,因为缩放就是视野上的缩小,对应的距离就是拉宽。

最后就是使用 CSS 的 transform 来做缩放:

transform: `scale(${this.scale/100})`

最终的效果:

Vue 实现一个简单的鼠标拖拽滚动效果插件

当前这个只是简单的一个排版,大家根据自己需要布局,这里主要还是分享一些思路,如果大家有好的思路,欢迎留言分享。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

以上就是Vue 实现一个简单的鼠标拖拽滚动效果插件的详细内容,更多关于vue 鼠标拖拽滚动插件的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue实现表格合并功能
Dec 01 Vue.js
如何在VUE中使用vue-awesome-swiper
Jan 04 Vue.js
vue实现按钮切换图片
Jan 20 Vue.js
Vue实现简单计算器
Jan 20 Vue.js
学习 Vue.js 遇到的那些坑
Feb 02 Vue.js
详解Vue的七种传值方式
Feb 08 Vue.js
用vite搭建vue3应用的实现方法
Feb 22 Vue.js
vue常用高阶函数及综合实例
Feb 25 Vue.js
详解vue身份认证管理和租户管理
May 25 Vue.js
vue使用echarts实现折线图
Mar 21 Vue.js
vue整合百度地图显示指定地点信息
Apr 06 Vue.js
Vue Mint UI mt-swipe的使用方式
Jun 05 Vue.js
vuex页面刷新导致数据丢失的解决方案
Dec 10 #Vue.js
详解vue-cli项目在IE浏览器打开报错解决方法
Dec 10 #Vue.js
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 #Vue.js
vue添加自定义右键菜单的完整实例
Dec 08 #Vue.js
vue中如何自定义右键菜单详解
Dec 08 #Vue.js
基于vue与element实现创建试卷相关功能(实例代码)
Dec 07 #Vue.js
vue祖孙组件之间的数据传递案例
Dec 07 #Vue.js
You might like
图象函数中的中文显示
2006/10/09 PHP
php生成SessionID和图片校验码的思路和实现代码
2009/03/10 PHP
Laravel 实现关系模型取出需要的字段
2019/10/10 PHP
Javascript-Mozilla和IE中的一个函数直接量的问题
2007/01/09 Javascript
Javascript(AJAX)解析XML的代码(兼容FIREFOX/IE)
2010/07/11 Javascript
JQuery入门—编写一个简单的JQuery应用案例
2013/01/03 Javascript
JS判断对象是否存在的10种方法总结
2013/12/23 Javascript
JavaScript中的原型和继承详解(图文)
2014/07/18 Javascript
jQuery中[attribute=value]选择器用法实例
2014/12/31 Javascript
浅谈javascript中的DOM方法
2015/07/16 Javascript
jquery validate表单验证的基本用法入门
2016/01/18 Javascript
原生js实现百叶窗效果及原理介绍
2016/04/12 Javascript
通用无限极下拉菜单的实现代码
2016/05/31 Javascript
js实现千分符和保留几位小数的简单实例
2016/08/01 Javascript
JS判断来路是否是百度等搜索索引进行弹窗或自动跳转的实现代码
2016/10/09 Javascript
AngularJS入门示例之Hello World详解
2017/01/04 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
2018/08/10 Javascript
react项目如何使用iconfont的方法步骤
2019/03/13 Javascript
node实现mock-plugin中间件的方法
2019/12/25 Javascript
vue-router路由懒加载及实现的3种方式
2021/02/28 Vue.js
python读取浮点数和读取文本文件示例
2014/05/06 Python
Django基础知识与基本应用入门教程
2018/07/20 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
2019/06/28 Python
python 解决cv2绘制中文乱码问题
2019/12/23 Python
PyTorch 解决Dataset和Dataloader遇到的问题
2020/01/08 Python
2020最新pycharm汉化安装(python工程狮亲测有效)
2020/04/26 Python
记一次django内存异常排查及解决方法
2020/08/07 Python
Anya Hindmarch官网:奢侈设计师手袋及配饰
2018/11/15 全球购物
香港草莓网:Strawberrynet香港
2019/05/10 全球购物
外企测试工程师面试题
2015/02/01 面试题
自荐书模板
2013/12/15 职场文书
演讲开场白和结束语
2015/05/29 职场文书
小学语文教学随笔
2015/08/14 职场文书
学校就业保障协议书
2019/06/24 职场文书
python数字图像处理:图像的绘制
2022/06/28 Python
Java Spring读取和存储详细操作
2022/08/05 Java/Android