锚点跳转

410 阅读1分钟
//父组件
<template>
  <div>
  <div class="content">
   <div class="left-content">
   <div class="left-content-max">
   <!-- <div v-for="(item,index) in leftdata" :key="index" :class="index===active?'active':''">
   {{item}}
   </div> -->
   <point :pointArr="leftdata"></point>
   </div>
   </div>
   <div class="right-content-max">
   <div class="right-content">
 <div v-for="(item,index) in leftdata" :key="index" :id="`point${index}`">
   {{item}}的内容
   </div>
   </div>
  
   
   </div>
  </div>
  
  </div>
</template>

<script>
import point from './point.vue'
export default {
    components:{
        point,
    },
    data() {
    return {
        leftdata:[],
        rightdata:[],
        active:0,
    }
  },
  created(){
      this.leftdata=Array.from({length:10}).map((item,index)=>{ return `列表${index}`})
  },
  methods: {

  },
};
</script>

<style>
/* .content{
    display:flex;
    max-height:100vh;
} */
/* .left-content{
    width:200px;
}
.left-content-max{
    height:1000px;
}
.right-content{
    
}
.right-content>div{
   height:500px;
   margin-top:10px;
   border:1px solid red;
}
.right-content>div:nth-child(1){
   margin-top:0;
}
.right-content-max{
    max-height:100vh;
    overflow: auto;
    flex-grow:1;
    margin-left:20px;
}
.left-content-max .active{
    color:red;
} */
.right-content{
    float:right;
}
.right-content>div{
   height:500px;
   width:1000px;
   margin-top:10px;
   border:1px solid red;
}
</style>
//子组件
<template>
    <div class="point">
        <div v-for="(x,i) in pointArr" :key="x" @click="selectPoint(i)">
        <i :class="{'select-i':isSelected === i}" ></i>
        <span :class="{'select-span':isSelected === i}">{{x}}</span>
        </div>

    </div>
</template>

<script>
export default {
    props:{
        pointArr:{
                type:Array,
                required:true
        }
    },
   created(){
   },
  data() {
    return {
        isEditorAdd:true,
        isSelected:0,
        scrollTop:0
    };
  },
  mounted(){
      window.addEventListener('scroll',this.scrollHandle)
  },
  methods: {
      selectPoint(i) {
          this.isSelected = i
          //监听页面滚动的距离
          const height = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
        //   跳转的位置距离上方的距离
          const domHeight =  document.getElementById(`point${i}`).offsetTop - 100
          let s = height - domHeight;
          console.log(height,domHeight);
          console.log(s);
          s = s < 0 ? Math.abs(s) : (s === 0 ? 0 : -s);
          window.scrollBy({top: s, behavior: 'smooth'});
        // let element = document.getElementById(`content${i}`)
        // console.log("element",element);
        // if(element){
        //     console.log(element.getBoundingClientRect())
        // }
      },
      scrollHandle(e) {
          this.scrollTop = document.body.scrollTop||document.documentElement.scrollTop;
        console.log(e);
      },
      destroyed() {
          window.removeEventListener('scroll',this.scrollHandle)
      }
      //offset系列
        // 获得元素距离带有定位父元素的位置,获得元素自身的大小宽高,不带单位
        //1、offsetTop:相对带有定位父元素上方的偏移  offsetLeft,没有offsetRight和offsetBottom
        //2、offsetHeight:返回自身包括padding,边框、内容区的宽度,不带单位  offsetHeight高度 包含padding、border
    //   scroll系列
        //1、 scrollTop:返回被卷去的上侧距离
        //2、 scrollLeft:返回被卷去的左侧距离
        //3、 scrollHeight:返回自身的高度,不含边框,不带单位
        
  },
};
</script>

<style>
.point{
    position:fixed;
    top: 0px;
    left:30px;
    transition:top .5s;
    cursor: pointer;
    /* margin-bottom: 20px; */
}
</style>