vue自动滚动列表组件,使用Vue实现一个简单的鼠标拖拽滚动效果插件
vue自动滚动列表组件,使用Vue实现一个简单的鼠标拖拽滚动效果插件https://github.com/qq449245884/vue-drag-scroll创建一个 vue 项目,这个就不细说的,我已经把原码发布到 github 上了,有兴趣自己看看:这里线索又断了。于是又回到飞书有类似功能的页面,然后仔细检查一下它页面的 DOM 结构,如下所示:发现有这一层,它把页面设置的很宽,很高,为了隐藏滚动条,所以设置overflow: hidden;,看了这一设置,突然灵光一现,难道它是用拖拽来触发滚动条的滚动,在细想,哇靠,这思路可行的,NB。
演示事例http://www.longstudy.club/vue-drag-scroll/index.html
最近在做一个新的项目,有个需求是这样的:
简单描述一下,就是鼠标拖动页面,整个页面会随着的鼠标的拖拽而移动,如果页面有内容,里面的内容也需要跟着拖动的外层整体移动。
一开始没啥思路,所以就发了个朋友圈,得到的答案挺多的,主要还是用拖拽之类的,但这个拖拽只是单个元素的拖动,我想要的整个视图的拖动。
这里线索又断了。
于是又回到飞书有类似功能的页面,然后仔细检查一下它页面的 DOM 结构,如下所示:
发现有这一层,它把页面设置的很宽,很高,为了隐藏滚动条,所以设置overflow: hidden;,看了这一设置,突然灵光一现,难道它是用拖拽来触发滚动条的滚动,在细想,哇靠,这思路可行的,NB。
准备上手试试创建一个 vue 项目,这个就不细说的,我已经把原码发布到 github 上了,有兴趣自己看看:
https://github.com/qq449245884/vue-drag-scroll
首先给外层加个大大的宽和高:
<divclass="vue-drag-scroll-wrapper":style="zoomStye">
//这里省略一些不太重要的代码
</div>
<script>
exportdefault{
name:'VueDragScroll'
props:{
msg:String
}
data(){
return{
scale:100
}
}
computed:{
zoomStye(){
constINIT_WIDTH=2208
constINIT_HEIGHT=1206
constwidth=INIT_WIDTH*(1 (100-this.scale)/100)
constheight=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,主要使用就是给外层加一个大的宽,和高,这里我还设置了一个缩放比较,为了是能放大缩小页面,下面讲。运行效果:
接着,我们需要监听鼠标的拖拽来触发滚动条效果,因为需要对 dom 的操作,所以这里把拖拽处理逻辑用 vue 指令封装起来,这样后面有需要,只要使用该指令即可。
注意:在 vue 中如果需要对 dom 进行多次操作,最好是把它封装在指令中。
指令代码如下:
importVuefrom'vue'
Vue.directive('dragscroll' function(el){
el.onmousedown=function(ev){
console.log(el)
constdisX=ev.clientX
constdisY=ev.clientY
constoriginalScrollLeft=el.scrollLeft
constoriginalScrollTop=el.scrollTop
constoriginalScrollBehavior=el.style['scroll-behavior']
constoriginalPointerEvents=el.style['pointer-events']
// auto:默认值,表示滚动框立即滚动到指定位置。
el.style['scroll-behavior']='auto'
el.style['cursor']='grabbing'
//鼠标移动事件是监听的整个document,这样可以使鼠标能够在元素外部移动的时候也能实现拖动
document.onmousemove=function(ev){
ev.preventDefault()
//计算拖拽的偏移距离
constdistanceX=ev.clientX-disX
constdistanceY=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 指令,我们来使用一下,首先我们需要在增加一层外层:
<divv-dragscrollclass="vue-drag-scroll-out-wrapper">
<divclass="vue-drag-scroll-wrapper":style="zoomStye">
//这里省略一些不太重要的代码
</div>
</div>
<stylescoped>
.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值,否则无法滚动(测试出来的)。
这样拖拽效果就出来啦:
这里,我们增加一个视图的放大和缩小,所以增加两个按钮:
<divclass="tolbox-zoom-wrapper">
<divclass="zoom-inner">
<span class="iconfonticonsuoxiao"
:class="{'disabled':scale===25}"style="font-size:22px"
@click="handleReduce"
/>
<span class="iconfonticonfangda"
:class="{'disabled':scale===100}"
@click="handleEnlarge"
/>
<divclass="scale-text">{{scale}}%</div>
</div>
</div>
效果:
这里的放大和缩小的逻辑就是通过我们增加减少 scale 来实现
handleReduce(){
if(this.scale===25)return
this.scale-=25
}
handleEnlarge(){
if(this.scale===100)return
this.scale =25
}
缩放比例的关系就是开关给出的代码:
constINIT_WIDTH=2208
constINIT_HEIGHT=1206
constwidth=INIT_WIDTH*(1 (100-this.scale)/100)
constheight=INIT_HEIGHT*(1 (100-this.scale)/100)
这个比例是我自己定的,比如现在减少到 75% ,那么最外层的高和宽就要对应的增加原来的 25%,因为缩放就是视野上的缩小,对应的距离就是拉宽。
最后就是使用 CSS 的 transform 来做缩放:
transform:`scale(${this.scale/100})`
最终的效果:
当前这个只是简单的一个排版,大家根据自己需要布局,这里主要还是分享一些思路,如果大家有好的思路,欢迎留言分享。