提交 | 用户 | 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> |