Implementation of vue scrolling selector effect (text dynamic effect)

1. First, the whole is a div, the scrolling effect is realized inside the div, and each data is a separate li.

     <div id="scroll" :v-model="dataPopRadio" class="solidUl" @scroll="scrollChange">
            <ul>
              <li
                v-for="(item, index) in dataPopOption"
                :key="index"
              >{
   
   {item.label}}</li>
            </ul>
//滚动过程中滚动到的所需位置
            <div class="backgroundFloat"></div>
     </div>

2. Define data in data

dataPopOption : [{
          name: '年假',
          label: '年假'
        }, {
          name: '事假',
          label: '事假'
        }, {
          name: '病假',
          label: '病假'
        }, {
          name: '倒休假',
          label: '倒休假'
        }, {
          name: '婚假',
          label: '婚假'
        }, {
          name: '产假',
          label: '产假'
        }, {
          name: '产检假',
          label: '产检假'
        },
      ]

3. Define the scrolling event in the method 

scrollChange(e){
//首先获取到li元素
      var lis=document.getElementsByTagName('li')
//对li元素进行遍历
      for(var i=0;i<lis.length;i++){
//offsetTop返回当前元素相对于节点顶部偏移量,scrollTop返回一个元素垂直滚动的距离
//在滚动过程中,lis[i].offsetTop-e.target.scrollTop可获取到当前元素距离顶部的位置
//打印出结果自己对比,选择自己需要范围的值,我给li设置的高度为40px,因此185与225之间相差40,
//而185与225是我实际输出对比测量的我需要元素滚动到该位置时设置样式。
        if((lis[i].offsetTop-e.target.scrollTop) > 185&& (lis[i].offsetTop-e.target.scrollTop) < 225){
//当元素滚动到当前位置时,先将元素原来为"active2"的class属性去掉
//再给元素增加"active"的属性
          lis[i].classList.remove("active2")
          lis[i].classList.add("active")
//给当前元素以上的元素动态设置文字大小,离当前文字越远,文字大小越小
          for(var j=1;j<=i;j++){
            lis[i-j].style.fontSize = (20-2*j)+'px'
          }
//给当前元素以下的元素动态设置文字大小,离当前文字越远,文字大小越小
          for(var a=1;a<lis.length-i;a++){
            lis[i+a].style.fontSize = (20-2*a)+'px'
          }
//当没滚动到期待位置时,也就是其他所有元素,移除"active"的样式,增加"active2"的样式
        }else{
          lis[i].classList.remove("active")
          lis[i].classList.add("active2")
        }
      }
    },

4. Set related styles in the style tag

.solidUl{
  padding-top: 40px;
  margin-top: 15px;
  height: 350px;
//滚动设置在div内
  overflow-y: scroll;
//增加滚动的流畅性
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}
ul {
      padding: 80px 0 230px 0;
      margin: 0;
      background-color: #fff;
      li {
        list-style: none;
        font-size: 18px;
        line-height: 20px;
        text-align: center;
        opacity: 0.3;
        height: 40px;
        background-color: #fff;
      }
    }
.active {
  font-weight: 400;
  font-size: 20px !important;
  color: #333;
//不透明度需要高点,因为有backgroundFloat颜色的影响
  opacity: 1.2 !important;
  top: 150px;
}
.active2 {
  color: #333;
//设置不透明度
  opacity: 0.6 !important;
}
//给滚动到的所需位置增加背景色等样式
.backgroundFloat{
  width: 100%;
  height: 40px;
  background-color: #d1d1d1;
//降低不透明度,以防遮挡文字
  opacity: 0.2;
  position: absolute;
  top: 190px;
}

5. Position the scroll bar in the event that needs to trigger scrolling. If there is data rendering at the same time, you need to call back the nextTick function to process asynchronously. If there is no update rendering of data, the nextTick function is not needed, just set it between.

//vue中数据和dom渲染是异步的,this.$nextTick函数是在dom更新循环之后进行回调
      this.$nextTick(() =>{
//滚动到指定位置。不然未触发滚动事件的时候样式字体大小的效果不对
//scrollTop() 方法设置或返回被选元素的垂直滚动条位置
        document.getElementById("scroll").scrollTop = 80
      })

I have data update here, if I don’t process it, I will report an error vue.esm.js?a026:628 [Vue warn]: Error in v-on handler (Promise/async): "TypeError: Cannot set properties of null (setting 'scrollTop')" , as follows :

6. The final effect. The text will change with scrolling, and the text size will be the largest when scrolling to the position where the background is gray.

Guess you like

Origin blog.csdn.net/qq_45079530/article/details/126365332