zhaoxiaoqiang1
2026-01-04 f1d30d03186c79ca2cbcfe60d6d2ce7d73fba97b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<template>
  <div>
    <slot></slot>
  </div>
</template>
<script>
/**
 * 滚动tab效果封装
 */
export default {
  props: {
    tabId: {
      type: String,
      default: ''
    },
    contentId: {
      type: String,
      default: ''
    },
    limit: {
      type: Number,
      default: 10
    },
    tabIndex: {
      type: Number,
      default: 0
    }
  },
  created() {
    this.init()
  },
  methods: {
    init() {
      this.$nextTick(() => {
        const { tabId, contentId } = this
        // 该元素需使用relative 或者 absolute定位,否则会导致后续获取子节点的offsetTop不准确
        const tabEle = this.getElement(tabId)
 
        // 该元素需使用relative 或者 absolute定位,否则会导致后续获取子节点的offsetTop不准确
        const contentEle = this.getElement(contentId)
 
        this.tabEle = tabEle
        this.contentEle = contentEle
        this.setEvent()
      })
    },
    setEvent() {
      const { contentEle, scrollEvent } = this
      contentEle.addEventListener('scroll', scrollEvent)
    },
    scrollEvent(event) {
      // const { limit } = this
      const ul = event.target
      const list = ul ? ul.children : null
 
      if (list) {
        // const ulHeight = ul.offsetHeight
        const ulScrollTop = ul.scrollTop
        const listArr = Array.from(list)
        // let loadingIndex = 0
        let tabIndex = 0
 
        listArr.forEach(({ offsetHeight, offsetTop }, index) => {
          if (ulScrollTop >= offsetTop - 20) {
            tabIndex = index
          }
        })
        tabIndex =
          tabIndex >= listArr.length - 1 ? listArr.length - 1 : tabIndex
        this.$emit('changeTab', tabIndex, false)
      }
    },
    getElement(str) {
      return document.querySelector(str)
    },
    setScrollTop(index, flg = true) {
      const { contentEle, tabIndex } = this
      index = isNaN(index) ? tabIndex : index
      this.removeEvent()
      let top = contentEle.children[index].offsetTop
      // 内容总高度
      // const contentHeight = Array.from(contentEle.children).reduce(
      //   (pre, { offsetHeight }) => pre + offsetHeight,
      //   0
      // )
      // if (top > contentHeight - contentEle.offsetHeight) {
      //   top = contentHeight - contentEle.offsetHeight
      // }
      if (flg) {
        contentEle.scrollTop = top
      }
      // this.setEvent()
      setTimeout(() => this.setEvent(), 100)
    },
    removeEvent() {
      const { contentEle, scrollEvent } = this
      contentEle.removeEventListener('scroll', scrollEvent)
    },
    setTabScrollTop() {
      const { tabEle, tabIndex } = this
      const tabHeight = tabEle.offsetHeight
      // 内容总高度
      const totalHeight = Array.from(tabEle.children).reduce(
        (pre, { offsetHeight }) => pre + offsetHeight,
        0
      )
 
      if (totalHeight > tabHeight) {
        let top = tabEle.children[tabIndex].offsetTop - tabHeight / 2
        top = top < 0 ? 0 : top
        top = top > totalHeight - tabHeight ? totalHeight - tabHeight : top
        tabEle.scrollTop = top
      }
    }
  },
  beforeDestroy() {
    this.removeEvent()
  }
}
</script>