美文网首页
Vue实现anchor锚点组件

Vue实现anchor锚点组件

作者: A郑家庆 | 来源:发表于2021-07-22 19:23 被阅读0次
<template>
    <div class="content-wrap" :style="{'overflow-y': isScroll ? 'scroll' : ''}" ref="scrollView">
        <div class="content">
            <div class="content-body markdown-body hljs" v-html="pageInfo.body"></div>
            <div class="content-right" v-if="navList && navList.length > 0">
                <div class="anchor-panel">
                    <el-aside>
                        <el-tabs @click="handleClick" v-model="activeName" tab-position="right" style="height:auto">
                            <el-tab-pane :name="'tab' + index"
                                :class="item.lev"
                                v-for="(item,index) in  navList"
                                :key="index"
                                :label="item.name"></el-tab-pane>
                        </el-tabs>
                    </el-aside>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                pageInfo: {},
                activeName: 'tab0',
                navList: [],
                isToggle: false,
                isShowBackTop: false,
                isScroll: false,
                scrollView: null,
                timeout: null
            }
        },
        mounted () {
            // 获取到页面数据之后
            this.$nextTick(() => this.selectAllTitle())
        },
        methods: {
            /**
             * 获取标题列表
             */
            selectAllTitle () {
                let titleList = document.querySelectorAll('h1,h2,h3')
                this.navList = Array.from(titleList)
                this.navList.forEach(el => {
                    el.name = el.innerText
                    let index = el.localName.indexOf('h')
                    el.lev = 'lev' + el.localName.substring(index + 1, el.localName.length)
                })
                clearTimeout(this.timeout)
                this.timeout = setTimeout(() => this.handlerStyle(), 400)
            },
            /**
             * 修改tab样式以及监听滚动
             */
            handlerStyle () {
                let navs = document.querySelectorAll('.el-tabs_item')
                for (let i = navs.length-1; i > 0; i--) {
                    let domStyle = document.querySelector('#'+navs[i].id).style
                    domStyle.paddingLeft = '0px'
                    if (this.navList[i].lev === 'lev1') {
                        domStyle.paddingLeft = '16px'
                        domStyle.fontSize = '14px'
                        domStyle.width = '170px'
                    } else if (this.navList[i].lev === 'lev2') {
                        domStyle.paddingLeft = '30px'
                        domStyle.fontSize = '12px'
                        domStyle.width = '170px'
                    } else if (this.navList[i].lev === 'lev3') {
                        domStyle.paddingLeft = '40px'
                        domStyle.fontSize = '12px'
                        domStyle.width = '170px'
                    }
                }
                this.scrollView = this.$refs.scrollView
                this.scrollView && this.scrollView.addEventListener('scroll', this.scrollEvent)
            },
            /**
             * 页面滚动
             */
            scrollEvent () {
                this.isScroll = true
                let scroll = this.scrollView.scrollTop
                this.isShowBackTop = scroll !== 0
                if (this.isToggle) return this.isToggle = false
                for (let i = this.navList.length - 1; i > 0; i--) {
                    if (scroll >= this.navList[i].offsetTop) {
                        this.activeName = 'tab' + i
                        break
                    }
                    if (scroll <= this.navList[0].offsetTop) {
                        this.activeName = 'tab' + 0
                    }
                }
            },
            /**
             * 切换tab
             */
            handleClick ({index}) {
                this.isToggle = true
                let domList = document.querySelectorAll('h1,h2,h3')
                this.scrollview.scrollTop = domList[index].offsetTop
                this.activeName = 'tab' + index
            }
        }
    }
</script>

相关文章

网友评论

      本文标题:Vue实现anchor锚点组件

      本文链接:https://www.haomeiwen.com/subject/tejymltx.html