vue自定义指令实现滚动div中的元素滚动到指定位置
参考:https://blog.csdn.net/ZTJ_123/article/details/103909346。1. src/directive/scroll.js:中写入自定义指令。import Vue from 'vue'//全局自定义指令给目标元素动画滚动到指定偏移位置 如果绑定值为true 则滚动到顶部Vue.directive('scroll-top', {/**** @param
·
参考:https://blog.csdn.net/ZTJ_123/article/details/103909346。
1. src/directive/scroll.js:中写入自定义指令。
import Vue from 'vue'
//全局自定义指令 给目标元素动画滚动到指定偏移位置 如果绑定值为true 则滚动到顶部
Vue.directive('scroll-top', {
/**
*
* @param {object} el
* @param {object} binding
* binding.value={
* allowScroll:false,是否允许滚动
* offset:0,滚动到距父元素上偏移量
* complete:()=>{},滚动结束的回调,用来初始化/还原绑定值
* }
*/
componentUpdated: function (el, binding, ) {
//是否允许滚动
let allowScroll = false
//目标偏移
let goalOffset = 0
//动画完成的回调
let completeCall = null
//速度因子
let divisor = 5
//如果绑定值是boolean类型 默认滚动到顶部
if (typeof binding.value == "boolean") {
allowScroll = binding.value
}
//如果绑定值是对象类型
if (binding.value && typeof binding.value == "object") {
allowScroll = binding.value.allowScroll || false
goalOffset = binding.value.offset || 0
completeCall = binding.value.complete
divisor = binding.value.divisor || 5
}
//获取html原生元素
const element = el.$el ? el.$el : el
//滚动逻辑
if (allowScroll == true) {
//如果偏移量 和目标偏移量相等 则不滚动 并执行回调方法
if (element.scrollTop == goalOffset) {
if (completeCall) {
//回调函数里记得把绑定值初始化 比如设为false
completeCall()
}
return
}
//判断滚动方向
let direction = 'up'
//目标偏移 大于当前偏移 需向上滚动 增加元素上偏移
if (goalOffset > element.scrollTop) {
//向上
direction = 'up'
} else {
//向下
direction = 'down'
}
//获取当前偏移和目标偏移的绝对差值
let offsetDiff = Math.abs(goalOffset - element.scrollTop)
//计时器 滚动逻辑
let timer = setInterval(() => {
//计算速度 向上舍入 速度最小为 1 这样element.scrollTop == goalOffset 最后必然成立
//注意 当offsetDiff小于divisor后 速度将恒为1 所以 divisor不不宜过大 建议设为5
let ispeed = Math.ceil(offsetDiff / divisor)
//计算剩余差值
offsetDiff = offsetDiff - ispeed
//根据滚动方向 判断偏移量是加是减
if (direction == 'up') {
element.scrollTop = element.scrollTop + ispeed
} else {
element.scrollTop = element.scrollTop - ispeed
}
//当前偏移 等于目标偏移 停止滚动 清除计时器 并执行回调方法
if (element.scrollTop == goalOffset) {
clearInterval(timer)
if (completeCall) {
//回调函数里记得把绑定值初始化 比如设为false
completeCall()
}
}
}, 16)
}
}
})
2. 全局引入自定义指令:在main.js中
import "@/directive/scroll.js"
3. 组件中使用:
<div class="my-scroll" v-scroll-top='scrollTop'>
<div class="year-text" v-for="(item,index) in 2" :key='index*0.77+47'></div>
<div class="year-text" :class="[selectYearItem===item && 'year-text-active']" ref='yearDom' v-for="(item,index) in yearList" :key='index*0.2+3' @click="selectYear(item,index)">{{item}}</div>
<div class="year-text" v-for="(item,index) in 2" :key='index*0.37+41'></div>
</div>
<script>
export default {
data(){
yearList:[2020,2019,2018,2017,2016,2015,2014,2013,2012,2011,2010,2009,2008,2007],
scrollTop:false,
selectYearItem:2020
},
mounted(){
this.selectYear(this.yearList[0],0)
},
methods:{
selectYear(item,index){
this.selectYearItem = item
this.$nextTick(()=>{
let offset= this.$refs.yearDom[index].offsetTop-100
this.scrollTop={
allowScroll: true,
offset:offset,
complete: ()=> {
this.scrollTop = false
}
}
})
},
}
}
</script>
<style lang='less' scoped>
.my-scroll{
overflow-y: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+ */
&::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
}
</style>
点击哪个年份,自动滚动到哪个年份。
更多推荐
已为社区贡献21条内容
所有评论(0)