实现给滚动元素添加多个锚点。并实现滚动过程对锚点样式实现反作用

实现给滚动元素添加多个锚点。并实现滚动过程对锚点样式实现反作用

给元素添加锚点,点击锚点可滚动到对应的元素

锚点的取得是通过滚动元素的数组tabList中获取,动态生成锚点,通过a标签的href 指定对应的ID来实现。
leftDiv包裹的元素是动态生成的锚点;需要锚点的滚动元素在rightDiv中,有动态id的元素;通过动态的ID数组获取动态的锚点。点击锚点可直接到相应的ID。

<el-tabs v-model="activeName" @tab-click="handleClick" >
        <el-tab-pane v-for="(once,index) in tabList" :key="index" :label="once.label" :name="once.name">
            <div class="coverDiv">
            <ul class="leftDiv" ref="leftDiv">
                <li v-for="twice in navLis" :key="twice.id">
                    <a :href="twice.href" :class="{ 'active': twice.isActive }"
                                        @click="clickFirst(twice.id)">{{ twice.h2 }}</a>
                </li>
            </ul>
            <div class="rightDiv">
                <div  v-for="item in once.list" :key="item.num" >
                    <div v-if="item.id" :id="item.id" :ref="item.id"></div>
                <h2 v-if="item.h2">{{ item.h2 }}</h2>
                <div v-if="item.html1" v-html="item.html1"></div>
                <h3 v-if="item.h3">{{ item.h3 }}</h3>
                <div v-if="item.code" style="position:relative" @mouseover="hover($event)" @mouseleave="leave($event)">
                    <prism-editor class="my-editor height-300 speWidth " v-model="item.code" :highlight="highlighter"
                        readonly line-numbers></prism-editor>
                    <div style="position:absolute;right:15px;top:15px;border-radius:2px;background-color:#eee;display:none;cursor: pointer; padding:2px 8px;"
                        @click="copyFn(item.num)">复制</div>
                </div>
			</div>
          </div>
        </div>
       </el-tab-pane>
       </el-tabs>
实现滚动元素对锚点反作用,即滚动到相应的位置,需要对应的锚点样式进行修改

mounted给滚动元素绑定滚动事件。
动态获取各个ID的位置,通过id在窗口中的显示位置,来判断当前需要有样式的锚点是哪个。

mounted() {
        this.addScroll()
    },
  methods: {
        addScroll(){
            const myDiv = document.getElementById('myDiv');
        let that = this
        // const leftDiv = document.getElementById('leftDiv');
        myDiv.addEventListener('scroll', function() {
            const scrollTop = myDiv.scrollTop; // 获取滚动条距离顶部的距离
            // const scrollHeight = myDiv.scrollHeight; // 获取可滚动区域的高度
            const clientHeight = myDiv.clientHeight; // 获取 div 元素的高度
          
            
            let middleLeftDiv = ""
            // let middleA = ''
            if(that.activeName === "firstTab"){
                middleLeftDiv = that.$refs.leftDiv[0]
                // middleA = "first"
            }
            if(that.activeName === "secondTab"){
                middleLeftDiv = that.$refs.leftDiv[1]
                // middleA = "pythonFirst"
            }
            if(that.activeName === "thirdTab"){
                middleLeftDiv = that.$refs.leftDiv[2]
                // middleA = "phpFirst"
            }
           
             if(scrollTop >= 272){
                let finalHeight = scrollTop - clientHeight + middleLeftDiv.clientHeight + 'px'
                middleLeftDiv.style.top = finalHeight  
            }else{
                middleLeftDiv.style.top = '0px'
                // that.rightA = middleA
            }
            that.idList.forEach(item=>{
                const second = that.$refs[item][0].getBoundingClientRect().top; //获取元素距离顶部的距离
          
          
          // 滚动元素反作用于锚点元素
          if(second >0 && second<clientHeight){
              that.rightA = item
          }

            })
           
        })

        },
        clickFirst(which) {
            this.rightA = which
        },
        handleClick() {
            if (this.activeName === 'firstTab') {
                this.rightA = "first"
            }
            if (this.activeName === 'secondTab') {
                this.rightA = "pythonFirst"
            }
            if (this.activeName === 'thirdTab') {
                this.rightA = "phpFirst"
            }
        },
        highlighter(code) {
            return highlight(code, languages.js)
        },
        hover(el) {
            el.currentTarget.lastElementChild.style.display = "block"
        },
        leave(el) {
            el.currentTarget.lastElementChild.style.display = "none"
        },
        copyFn(num) {
            const textToCopy = this[num];
            // 使用Clipboard API将文本复制到剪贴板
            window.navigator.clipboard
                .writeText(textToCopy)
                .then(() => {
                    this.$message.success("复制成功")
                })
                .catch((error) => {
                    this.$message.error(`复制文本到剪贴板时出错:${error}`)
                });
        },},

<template>
    <div >
       <el-dialog title="示例代码SDK" id="myDiv" :visible.sync="codeExamples" :close-on-click-modal="false" :close-on-press-escape="false">
            <el-tabs v-model="activeName" @tab-click="handleClick" >
        <el-tab-pane v-for="(once,index) in tabList" :key="index" :label="once.label" :name="once.name">
            <div class="coverDiv">
            <ul class="leftDiv" ref="leftDiv">
                <li v-for="twice in navLis" :key="twice.id">
                    <a :href="twice.href" :class="{ 'active': twice.isActive }"
                                        @click="clickFirst(twice.id)">{{ twice.h2 }}</a>
                </li>
            </ul>
            <div class="rightDiv">
                <div  v-for="item in once.list" :key="item.num" >
                    <div v-if="item.id" :id="item.id" :ref="item.id"></div>
                <h2 v-if="item.h2">{{ item.h2 }}</h2>
                <div v-if="item.html1" v-html="item.html1"></div>
                <h3 v-if="item.h3">{{ item.h3 }}</h3>
                <div v-if="item.code" style="position:relative" @mouseover="hover($event)" @mouseleave="leave($event)">
                    <prism-editor class="my-editor height-300 speWidth " v-model="item.code" :highlight="highlighter"
                        readonly line-numbers></prism-editor>
                    <div style="position:absolute;right:15px;top:15px;border-radius:2px;background-color:#eee;display:none;cursor: pointer; padding:2px 8px;"
                        @click="copyFn(item.num)">复制</div>
                </div>
			</div>
          </div>
        </div>
       </el-tab-pane>
    </el-tabs>
   </el-dialog>
</div>
</template>
  <script>
import ApiList from "@/components/TabPages/ApiList";
import ResponseCode from "@/components/TabPages/ResponseCode";
import PublicPrivateGeneration from "@/components/TabPages/PublicPrivateGeneration";
// import Prism Editor
import { PrismEditor } from 'vue-prism-editor'
import 'vue-prism-editor/dist/prismeditor.min.css'
// import highlighting library
import { highlight, languages } from 'prismjs/components/prism-core'
import 'prismjs/components/prism-clike'
import 'prismjs/components/prism-javascript'
import 'prismjs/themes/prism-tomorrow.css'
import {
    javaCode1,
    javaCode2,
    javaCode3,
    javaCode4,
    javaCode5,
    javaCode6,
    javaCode7,
    javaCode8,
    javaCode9,
    javaCode10,
    javaCode11,
    javaCode12,
    javaCode13,
    javaCode14,
    javaCode15,
    javaCode16,
    phpCode1,
    phpCode2,
    phpCode3,
    phpCode4,
    phpCode5,
    pythonCode1,
    pythonCode2,
    pythonCode3,
    pythonCode4,
    pythonCode5,
    pythonCode6,
} from "@/utils/markdown"
export default {
    created() {},
    mounted() {
        this.addScroll()
    },
    data() {
        return {
            rightA: "first",
	        activeName: "firstTab",
	        javaCode1,
	        javaCode2,
	        javaCode3,
	        javaCode4,
	        javaCode5,
	        javaCode6,
	        javaCode7,
	        javaCode8,
	        javaCode9,
	        javaCode10,
	        javaCode11,
	        javaCode12,
	        javaCode13,
	        javaCode14,
	        javaCode15,
	        javaCode16,
	        phpCode1,
	        phpCode2,
	        phpCode3,
	        phpCode4,
	        phpCode5,
	        pythonCode1,
	        pythonCode2,
	        pythonCode3,
	        pythonCode4,
	        pythonCode5,
	        pythonCode6,
	       tabList: [{
	            name: "firstTab",
	            label: "JAVA",
	            list: [
	                {
	                    id: "first",
	                    h2: "RSA2签名",
	                    h3: "报文签名算法",
	                    h4: "",
	                    html1: `此方法在请求类接口交易中,报文头signMethod取值为“RSA2”时使用,
	                    对“待签字符串”进行RSA签名,为了保证双方的身份可靠性和数据完整性。</br>主要步骤如下:</br>
	                    1.代签字符串用SHA-256算法生成摘要</br>
	                    2.使用接入方RSA秘钥对的私钥对摘要做签名,生成签名值</br>
	                    3.对签名值做Base64编码,放到http消息头的sign字段中</br>
	                    4.签名算法,填写在http消息头的signMethod字段中`,
	                    code: javaCode1,
	                    num: "javaCode1"
	                },
	                {
	                    h3: "SHA256签名算法",
	                    code: javaCode2,
	                    num: "javaCode2"
	                },
	                {
	                    h3: "RSA签名算法",
	                    code: javaCode3,
	                    num: "javaCode3"
	                },
	                {
	                    html1: `*注1 privateKey(私钥):可于开放平台用工具生成公私钥对,将生成的公钥通过开放平台-个人中心-相应的API认证账号-RSA2验签公钥进行设置;对应生成的私钥请保存好`,
	                    num: "1004"
	                },
	                {
	                    id: "second",
	                    h2: "RSA2验签",
	                    h3: "通知报文验签样例代码",
	                    h4: "",
	                    html1: `此方法在通知类接口交易中,用“待签字符串”和验签公钥,对通知报文的
	                    签名做验签,为了保证请求来源的身份可靠性和报文完整性。</br>
	                    主要步骤如下:</br>
	                    1.从http消息头中获取signMethod;</br>
	                    2.对待签名串使用SHA-256算法生成摘要;</br>
	                    3.从http消息头中获取sign,对sign做base64解码;</br>
	                    4.从开放平台API认证账号处获取接收方通知验签公钥;</br>
	                    5.对第3步解码后的sign值,用第4步获取的公钥进行验签`,
	                    num: "1005"
	                },
	                {
	                    h3: "RSA2验签样例代码:SHA-256算法生成摘要",
	                    code: javaCode11,
	                    num: "javaCode11"
	                },
	                {
	                    h3: "RAS验签算法",
	                    code: javaCode12,
	                    num: "javaCode12"
	                },
	                {
	                    id: "third",
	                    h2: "SM2签名",
	                    h3: "引用jar包",
	                    h4: "",
	                    html1: `
	                此方法在请求类接口交易中,报文头signMethod取值为“SM2”时使用,对“待签字符串”进行SM2签名
	                ,为了保证双方的身份可靠性和数据完整性。</br>主要步骤如下:</br>
	                1.代签字符串用SM3算法生成摘要</br>
	                2.使用接入方SM2秘钥对的私钥对摘要做签名,生成签名值</br>
	                3.对签名值做Base64编码,放到http消息头的sign字段中</br>
	                4.签名算法,填写在http消息头的signMethod字段中`,
	                    code: javaCode4,
	                    num: "javaCode4"
	                }, {
	                    h3: "实体类结构",
	                    code: javaCode5,
	                    num: "javaCode5"
	                }, {
	                    h3: "获得公私钥对",
	                    code: javaCode6,
	                    num: "javaCode6"
	                }
	                , {
	                    h3: "SM3摘要算法",
	                    code: javaCode7,
	                    num: "javaCode7"
	                }
	                , {
	                    h3: "SM2签名算法",
	                    code: javaCode8,
	                    num: "javaCode8"
	                }
	                , {
	                    h3: "对SM2Signature 对象进行加密,获得sign值",
	                    code: javaCode9,
	                    num: "javaCode9"
	                }, {
	                    h3: "获得转换后的公钥加密串,为了验签用",
	                    html1: `将生成的公钥通过开放平台-个人中心-相应的API认证账号-SM2验签公钥进行设置;
	                对应生成的私钥请保存好`,
	                    code: javaCode10,
	                    num: "javaCode10"
	                }, {
	                    id: "fourth",
	                    h2: "SM2验签",
	                    h3: "SM2验签样例代码:BC工具生成待签字符串摘要",
	                    code: javaCode13,
	                    num: "javaCode13"
	                }, {
	                    h3: "SM2验签算法",
	                    code: javaCode14,
	                    num: "javaCode14"
	                }, {
	                    id: "fifth",
	                    h2: "SM4加密",
	                    code: javaCode15,
	                    num: "javaCode15"
	                }, {
	                    id: "sixth",
	                    h2: "接口调用",
	                    code: javaCode16,
	                    num: "javaCode16"
	                }
	            ]
	        },
	        {
	            name: "secondTab",
	            label: "python",
	            list: [
	                {
	                    id: "pythonFirst",
	                    h2: "RSA2签名",
	                    code: pythonCode1,
	                    num: "pythonCode1"
	                },
	                {
	                    id: "pythonSecond",
	                    h2: "RSA2验签",
	                    code: pythonCode2,
	                    num: "pythonCode2"
	                },
	                {
	                    id: "pythonThird",
	                    h2: "SM2签名",
	                    code: pythonCode3,
	                    num: "pythonCode3"
	                },
	                {
	                    id: "pythonFourth",
	                    h2: "SM2验签",
	                    code: pythonCode4,
	                    num: "pythonCode4"
	                },
	                {
	                    h3: "SM3",
	                    code: pythonCode5,
	                    num: "pythonCode5"
	                },
	                {
	                    id: "pythonFifth",
	                    h2: "SM4加密",
	                    code: pythonCode6,
	                    num: "pythonCode6"
	                } 
	            ]
	        },
	        {
	            name: "thirdTab",
	            label: "PHP",
	            list: [
	                {
	                    id: "phpFirst",
	                    h2: "RSA2签名",
	                    code: phpCode1,
	                    num: "phpCode1"
	                },
	                {
	                    id: "phpSecond",
	                    h2: "RSA2验签",
	                    code: phpCode2,
	                    num: "phpCode2"
	                },
	                {
	                    id: "phpThird",
	                    h2: "SM2签名",
	                    code: phpCode3,
	                    num: "phpCode3"
	                }, {
	                    id: "phpFourth",
	                    h2: "SM2验签",
	                    code: phpCode4,
	                    num: "phpCode4"
	                },
	                {
	                    id: "phpFifth",
	                    h2: "SM4加密",
	                    code: phpCode5,
	                    num: "phpCode5"
	                },
	                {
	                    id: "phpSixth",
	                    h2: "接口调用",
	                }
	            ]
	        },
	    ],
	};
   },
    components: {
        PrismEditor
    },
    computed: {
        // 获取a标签
        navLis(){
            let middleArr = []
            if(this.activeName === "firstTab"){
                middleArr = this.tabList[0]["list"].filter(item=>{return !!item.id})
            }
            if(this.activeName === "secondTab"){
              
                middleArr = this.tabList[1]["list"].filter(item=>{return !!item.id})
            }
            if(this.activeName === "thirdTab"){
                middleArr = this.tabList[2]["list"].filter(item=>{return !!item.id})
            } 
            return middleArr.map(twice=>{
                twice["href"] = `#${twice.id}`
                twice["isActive"] = this.rightA === twice.id
                return twice
            })
        },
        idList(){
            let middleArr = []
            if(this.activeName === "firstTab"){
                middleArr = this.tabList[0]["list"].filter(item=>{return !!item.id})
            }
            if(this.activeName === "secondTab"){
              
                middleArr = this.tabList[1]["list"].filter(item=>{return !!item.id})
            }
            if(this.activeName === "thirdTab"){
                middleArr = this.tabList[2]["list"].filter(item=>{return !!item.id})
            } 
            return middleArr.map(third=>third["id"])
        }
      },
    methods: {
        addScroll(){
            const myDiv = document.getElementById('myDiv');
        let that = this
        // const leftDiv = document.getElementById('leftDiv');
        myDiv.addEventListener('scroll', function() {
            const scrollTop = myDiv.scrollTop; // 获取滚动条距离顶部的距离
            // const scrollHeight = myDiv.scrollHeight; // 获取可滚动区域的高度
            const clientHeight = myDiv.clientHeight; // 获取 div 元素的高度
          
            
            let middleLeftDiv = ""
            // let middleA = ''
            if(that.activeName === "firstTab"){
                middleLeftDiv = that.$refs.leftDiv[0]
                // middleA = "first"
            }
            if(that.activeName === "secondTab"){
                middleLeftDiv = that.$refs.leftDiv[1]
                // middleA = "pythonFirst"
            }
            if(that.activeName === "thirdTab"){
                middleLeftDiv = that.$refs.leftDiv[2]
                // middleA = "phpFirst"
            }
           
             if(scrollTop >= 272){
                let finalHeight = scrollTop - clientHeight + middleLeftDiv.clientHeight + 'px'
                middleLeftDiv.style.top = finalHeight  
            }else{
                middleLeftDiv.style.top = '0px'
                // that.rightA = middleA
            }
            that.idList.forEach(item=>{
                const second = that.$refs[item][0].getBoundingClientRect().top; //获取元素距离顶部的距离
          
          
          // 滚动元素反作用于锚点元素
          if(second >0 && second<clientHeight){
              that.rightA = item
          }

            })
           
        })

        },
        clickFirst(which) {
            this.rightA = which
        },
        handleClick() {
            if (this.activeName === 'firstTab') {
                this.rightA = "first"
            }
            if (this.activeName === 'secondTab') {
                this.rightA = "pythonFirst"
            }
            if (this.activeName === 'thirdTab') {
                this.rightA = "phpFirst"
            }
        },
        highlighter(code) {
            return highlight(code, languages.js)
        },
        hover(el) {
            el.currentTarget.lastElementChild.style.display = "block"
        },
        leave(el) {
            el.currentTarget.lastElementChild.style.display = "none"
        },
        copyFn(num) {
            const textToCopy = this[num];
            // 使用Clipboard API将文本复制到剪贴板
            window.navigator.clipboard
                .writeText(textToCopy)
                .then(() => {
                    this.$message.success("复制成功")
                })
                .catch((error) => {
                    this.$message.error(`复制文本到剪贴板时出错:${error}`)
                });
        },},
};
</script>
<style lang="less" scoped>
/deep/ .el-tabs__nav-wrap::after {
    background-color: transparent !important;
}
.el-dropdown-link {
    cursor: pointer;
    color: black;
}
.el-icon-arrow-down {
    font-size: 12px;
}
.versionIntroduction{
    display:flex;
    padding: 0 15px;
    strong{
        width:78px;
	}
    p{
       margin:0;
       flex:1;
       }
}
.rightDiv {
    width: calc(100%-65px);
    padding-left: 65px;
}
.coverDiv {
    position: relative;
}
.leftDiv {
    width: 65px;
    padding-left:0;
    margin-top:0;
	position: absolute;
	left:0;
	top:0;
	a {
        text-decoration: none;
        color:#606266;
	}
	.active {
        color: #409EFF;
	}
}
.speWidth {
    width: calc(~"100% - 15px");
}

/* required class */
.my-editor {
    /* we dont use `language-` classes anymore so thats why we need to add background and text color manually */
    background: #2d2d2d;
    color: #ccc;
    /* you must provide font-family font-size line-height. Example: */
    font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
    font-size: 14px;
    line-height: 1.5;
    padding: 5px;
}

/* optional class for removing the outline */
.prism-editor__textarea:focus {
    outline: none;
}

/* not required: */
.height-300 {
    max-height: 300px;
}

p {
    text-align: left;
}

h2,
h3,
h4,
div {
    text-align: left;
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue实现滚动监听到锚点,可以通过以下步骤: 1. 在需要监听滚动的容器上,绑定 `@scroll` 事件。 2. 通过 `getBoundingClientRect()` 方法获取每个锚点元素的位置信息,得到它们距离容器顶部的距离。 3. 在滚动事件处理函数中,获取当前容器滚动的距离,并与每个锚点元素的位置信息进行比较,判断当前容器滚动到了哪个锚点的位置。 4. 将滚动到的锚点信息保存在 Vue 实例的数据中,并在模板中根据该数据展示对应的内容。 以下是一个简单的示例代码: ```vue <template> <div class="scroll-container" @scroll="handleScroll"> <div class="section" v-for="(section, index) in sections" :key="index"> <h2>{{ section.title }}</h2> <p>{{ section.content }}</p> </div> </div> </template> <script> export default { data() { return { activeSection: 0, // 默认选中第一个锚点 sections: [ { title: "Section 1", content: "Content 1" }, { title: "Section 2", content: "Content 2" }, { title: "Section 3", content: "Content 3" }, { title: "Section 4", content: "Content 4" }, ], }; }, mounted() { this.calculatePositions(); }, methods: { calculatePositions() { // 获取每个锚点元素的位置信息 this.positions = this.sections.map((section) => { const element = document.getElementById(section.title); return { title: section.title, top: element.getBoundingClientRect().top + this.$refs.container.scrollTop, }; }); }, handleScroll() { const scrollTop = this.$refs.container.scrollTop; // 判断当前滚动到了哪个锚点 for (let i = 0; i < this.positions.length; i++) { const position = this.positions[i]; if (scrollTop >= position.top && scrollTop < position.top + 400) { this.activeSection = i; break; } } }, }, }; </script> ``` 在该示例中,使用 `getBoundingClientRect()` 方法获取每个锚点元素的位置信息,并保存在 `positions` 数组中。在滚动事件处理函数中,获取当前容器滚动的距离,并与每个锚点元素的位置信息进行比较,判断当前容器滚动到了哪个锚点的位置。最后将滚动到的锚点信息保存在 `activeSection` 中,用于在模板中展示对应的内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值