long
2021-09-13 f84ee2c0436617048ed3457a4dfe5582fc140539
提交 | 用户 | age
2a61f6 1 <template>
L 2   <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
3     <slot />
4   </el-scrollbar>
5 </template>
6
7 <script>
8 const tagAndTagSpacing = 4 // tagAndTagSpacing
9
10 export default {
11   name: 'ScrollPane',
12   data() {
13     return {
14       left: 0
15     }
16   },
17   computed: {
18     scrollWrapper() {
19       return this.$refs.scrollContainer.$refs.wrap
20     }
21   },
22   mounted() {
23     this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
24   },
25   beforeDestroy() {
26     this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
27   },
28   methods: {
29     handleScroll(e) {
30       const eventDelta = e.wheelDelta || -e.deltaY * 40
31       const $scrollWrapper = this.scrollWrapper
32       $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
33     },
34     emitScroll() {
35       this.$emit('scroll')
36     },
37     moveToTarget(currentTag) {
38       const $container = this.$refs.scrollContainer.$el
39       const $containerWidth = $container.offsetWidth
40       const $scrollWrapper = this.scrollWrapper
41       const tagList = this.$parent.$refs.tag
42
43       let firstTag = null
44       let lastTag = null
45
46       // find first tag and last tag
47       if (tagList.length > 0) {
48         firstTag = tagList[0]
49         lastTag = tagList[tagList.length - 1]
50       }
51
52       if (firstTag === currentTag) {
53         $scrollWrapper.scrollLeft = 0
54       } else if (lastTag === currentTag) {
55         $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
56       } else {
57         // find preTag and nextTag
58         const currentIndex = tagList.findIndex(item => item === currentTag)
59         const prevTag = tagList[currentIndex - 1]
60         const nextTag = tagList[currentIndex + 1]
61
62         // the tag's offsetLeft after of nextTag
63         const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
64
65         // the tag's offsetLeft before of prevTag
66         const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
67
68         if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
69           $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
70         } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
71           $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
72         }
73       }
74     }
75   }
76 }
77 </script>
78
79 <style lang="scss" scoped>
80 .scroll-container {
81   white-space: nowrap;
82   position: relative;
83   overflow: hidden;
84   width: 100%;
85   ::v-deep {
86     .el-scrollbar__bar {
87       bottom: 0px;
88     }
89     .el-scrollbar__wrap {
90       height: 49px;
91     }
92   }
93 }
94 </style>