js控制web頁面滾動距離 鼠標滾輪移動距離控制 通過合理滾動距離提高web頁面體驗感


該種實現方式不同於輪播等css控制,可以直接嵌入到web頁面,不會破壞頁面結構,即拿即用。

需求分析

web端頁面如果採用長頁面模式,參考特斯拉官網,對於在同一頁面需要展示很多圖片內容的網站來說,通常瀏覽器默認的滾動條一次滾動的距離,對於用戶體驗很不友好,同時對於頁面完整性的展示效果也有影響,比如
三星官網
這種長頁面,用戶需要頻繁使用滾輪。
參考特斯拉官網之後,使用js實現了使用鼠標滾輪,控制滾動條的滾動距離,讓用戶在一次滾輪滾動中,可以看到一個完整的頁面。

效果

對比

正常滾動 滾動控制
在這裏插入圖片描述 在這裏插入圖片描述

實現思路

首先明確,我們的頁面中有多少需要滾動定位的元素,比如有這樣一個列表[ele1,ele2,ele3],當用戶滾動滾輪時,需要暫時讓滾輪事件停止響應,因爲滾輪事件的觸發條件是滾輪裏的卡點(滾動時明顯的停頓感)每動一下就要觸發,所以一次觸發後需要先停止一會(防止反覆觸發),並且,在觸發後,如果由代碼實現滾動,還需要阻止用戶滾輪的默認行爲,否則兩種滾動方式都會運行,頁面會卡住不動。
明確滾輪事件的原理之後,需要確認是向上滾動還是向下,一次滾動的距離是多少。根據滾輪事件,向上向下很好判斷。滾動距離需要根據實際情況,比如,我們在頁面中抓了3個點,獲取這3個點距離文檔頂部的距離就可以了,之後實現頁面滾動的函數,讓頁面滾動到我們希望的位置。

技術點/知識點

需要了解一下技術點:

  1. preventDefault ,阻止瀏覽器默認事件;
  2. window.scrollTo 頁面進行滾動;
  3. mousewheel 鼠標滾輪觸發事件;
  4. document.querySelector 選取頁面元素;
  5. element.offsetTop 當前元素距離文檔頂部距離;
    瞭解了這幾點,就能實現我們的需求了。
    在代碼中,
    有2個關鍵的變量,一個是cur_index,描述當前滾動到哪個元素。
    invoke,描述當前是否在滾動中,在moveTo函數中,先判斷該變量,避免重複觸發。

踩坑記錄

最開始期望使用scroll事件,控制瀏覽器的滾動條。實際編寫時發現,監聽scroll事件時,改變高度是無效的。
原因是scroll事件監聽的是,任何改變文檔位置的觸發的函數或者用戶觸發的動作,所以當監聽用戶動作時,改變文檔高度是不可行的,這會循環觸發scroll事件,導致頁面不停觸發scroll,不能實現該功能。
而mousewheel事件只監聽滾輪,所以最終實現了該功能。

示例代碼

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<style>
  .a,.b,.c{
    width: 100%;
    height: 100vh;
    background:red;
  }
  .b{
    background: blue;
  }
  .other{
    width: 100%;
    height: 30vh;
    background:black;
  }
  .other_1{
    background:white;
  }
  .other_2{
    background:black;
  }
  .other_3{
    background:white;
  }
</style>
<body>
  <div class="other other_0"></div>
  <div class="other other_1"></div>
  <div class="other other_2"></div>
  <div class="other other_3"></div>
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <script>
    window.addEventListener("mousewheel",WheelGo)

  var cur_index = -1
  var invoke = false
  list = [{ele:"other_0"},{ele:"other_1"},{ele:"other_2"},{ele:"other_3"},{ ele: "a" }, { ele: "b" }, { ele: "c" }]
  list = initSrollPosition("body",list)

  function initSrollPosition(ele,list){
  
    var container = document.querySelector(ele)
    for(var i in list){
      list[i].position = document.querySelector("."+list[i].ele).offsetTop
    }
    return list
  }
  //window.addEventListener("mousewheel",go)
    //
    // window.addEventListener("scroll",judge)
    // function judge(e){
    //   console.log(e)
    //   var scrollPosition = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
      
    //   var first_position = list[0].position/2
    //   console.log(scrollPosition)
    //   if(scrollPosition>=first_position){
       
    //   }
        
    // }

    // function loseWheelControl(){
      
    //     window.removeEventListener("mousewheel",go)
    //     console.log("loseWheelControl")
     
    // }

    function stopDefault(e){
     e.preventDefault()
     return false
    }

    function WheelGo(e){
      //判斷當前所處位置
     
      var isDown = e.deltaY>0?true:false

      stopDefault(e)
      if(invoke){
      return
    }
      moveTo(isDown)

        
    }
    function moveTo(isDown){
    var cur_state
    if(isDown){
      cur_index = cur_index>=list.length-1?list.length-1:cur_index+1
      var cur_state = list[cur_index]
    }else{
      cur_index = cur_index<=0?0:cur_index-1
       cur_state = list[cur_index]
    }
   
    console.log("invoke")
 
    invoke = true
    
      window.scrollTo({top:(cur_state.position),left:0,behavior:"smooth"})
      
      setTimeout(()=>{
        invoke = false
      },500)
    }
    
  </script>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章