分享一个vue开发TIPS:滚动条选中元素自动滚动到可视区域里居中显示。
模拟vant的Tab标签页的标签滚动效果
效果:选中元素,在滚动条的可视区域里面自动居中,头尾两端不用居中。
看下基本效果:
来看下代码:
<template> <div> <div class="scroll-box" ref="scrollBox"> <div ref="scrollItem" class="item" :class="{ active: currentIndex == index }" v-for="(item, index) in 10" :key="index" > {{ index }} </div> </div> <div class="tips">点击加减号改变索引再点击启动按钮,观察滚动!!!</div> <div>当前索引是:{{ currentIndex }}</div> <div class="input-box"> <div class="action"> <div class="item" @click="reduce">-</div> <div class="item num">{{ currentIndex }}</div> <div class="item" @click="add">+</div> </div> <div class="start" @click="start">启动</div> </div> </div></template><script>export default { data() { return { currentIndex: 0 } }, methods: { add() { this.currentIndex++ }, reduce() { this.currentIndex-- }, start() { /** * 1)先让选中的元素滚到可视区域的最左边 scrollLeft * 2)接着向右移动容器一半的距离 containWidth / 2 * 3)最后向左移动item一半的距离 offsetWidth / 2 */ let lastSpot = this.$refs.scrollBox.scrollLeft const nextSpace = 7 //每次移动距离 let scrollItemTimer = setInterval(() => { this.$nextTick(() => { let offsetWidth = this.$refs.scrollItem[this.currentIndex].offsetWidth //item let scrollLeft = this.$refs.scrollItem[this.currentIndex].offsetLeft //选中的元素滚到可视区域的最左边 const containWidth = this.$refs.scrollBox.offsetWidth //容器的宽度 let resultSpot = scrollLeft + offsetWidth / 2 - containWidth / 2 //最终要停留的点 if (Math.abs(lastSpot - resultSpot) < nextSpace) { clearInterval(scrollItemTimer) } if (resultSpot >= lastSpot) { lastSpot = lastSpot + nextSpace } else { lastSpot = lastSpot - nextSpace } this.$refs.scrollBox.scrollTo(lastSpot, 0) }) }, 15) } } }</script><style lang="less" scoped>.scroll-box { margin-top: 50px; width: 330px; height: 40px; background-color: #ddd; white-space: nowrap; overflow-y: hidden; overflow-x: scroll; .item { display: inline-block; height: 100%; width: 90px; border-radius: 5px; background-color: #ff0; margin-right: 10px; text-align: center; line-height: 40px; } .item:nth-last-of-type(1) { margin-right: 0; } } .active { background-color: #0ff !important; } .tips { margin-top: 30px; font-weight: 700; color: #1989fa; } .input-box { width: 100%; display: flex; align-items: center; .action { display: flex; align-items: center; .item { width: 40px; height: 40px; background-color: #07c160; color: #fff; text-align: center; line-height: 40px; border-radius: 10px; margin-right: 5px; } .item.num { background-color: #ff976a; } } .start { width: 80px; height: 40px; background-color: #1989fa; color: #fff; margin-left: 100px; text-align: center; line-height: 40px; border-radius: 10px; } }</style>
大家放到软件里试试吧!
网友评论文明上网理性发言 已有0人参与
发表评论: