1. 原先側邊欄是絕對定位(相對於body來定位)
2. 當頁面滾動到一定位置時(header部分全部被卷去時),側邊欄改為固定定位
3. 頁面繼續滾動,會讓“返回頂部”顯示出來(滾動到main區域時,顯示“返回頂部”)
- 需要用到頁面滾動事件scroll,因為是頁面滾動,所以事件源是document
- 滾動到某個位置,就是判斷頁面被卷去的上部值
- 頁面被卷去的頭部:可以通過window.pageYOffset獲得。如果是被卷去的左側,則使用window.pageXOffset
注意,元素被卷去的頭部是element.scrollTop,如果是頁面被卷去的頭部則是window.pageYOffset
4. 返回頂部的功能:
- 帶有動畫的返回頂部:此時可以使用封裝好的動畫函數,只需要把所有的left相關的值改為跟頁面垂直滾動距離相關就可以了
- 頁面滾動了多少,可以通過window.pageYOffset得到
- 最后是頁面滾動,返回到頂部,滾動窗口至文檔中的特定位置,使用window.scroll(x, y)
<!-- CSS樣式 --> <style> .slider-bar { position: absolute; left: 50%; top: 300px; margin-left: 600px; width: 45px; height: 130px; background-color: pink; } .w { width: 1200px; margin: 10px auto; } .header { height: 150px; background-color: purple; } .banner { height: 250px; background-color: skyblue; } .main { height: 1000px; background-color: yellowgreen; } span { display: none; position: absolute; bottom: 0; } </style>
<!-- slider-bar是相對於body定位的,body的頭部是header,也就是當slider-bar是相對定位時,距離header的距離為300px --> <div class="slider-bar"> <span class="goBack">返回頂部</span> </div> <div class="header w">頭部區域</div> <div class="banner w">banner區域</div> <div class="main w">主體部分</div> <script> //1. 獲取元素 var sliderbar = document.querySelector('.slider-bar'); var banner = document.querySelector('.banner'); // banner.offestTop 就是被卷去頭部的大小 一定要寫到滾動的外面 var bannerTop = banner.offsetTop // 當我們側邊欄固定定位之后應該變化的數值 var sliderbarTop = sliderbar.offsetTop - bannerTop; // 獲取main 主體元素 var main = document.querySelector('.main'); var goBack = document.querySelector('.goBack'); var mainTop = main.offsetTop; // 2. 頁面滾動事件 scroll document.addEventListener('scroll', function() { // window.pageYOffset 頁面被卷去的頭部 // console.log(window.pageYOffset); // 3 .當我們頁面被卷去的頭部大於等於了 172 此時 側邊欄就要改為固定定位 if (window.pageYOffset >= bannerTop) { sliderbar.style.position = 'fixed'; // 注意:變成固定定位后,top值也要改,否則側邊欄會跳下來 sliderbar.style.top = sliderbarTop + 'px'; } else { sliderbar.style.position = 'absolute'; sliderbar.style.top = '300px'; } // 4. 當我們頁面滾動到main盒子,就顯示 goback模塊 if (window.pageYOffset >= mainTop) { goBack.style.display = 'block'; } else { goBack.style.display = 'none'; } }); // 5. 當點擊了返回頂部模塊,就讓窗口滾動到頁面的最上方 goBack.addEventListener('click', function() { // 里面的x和y不跟單位,直接寫數字即可 // 因為是窗口滾動,所以對象是window animate(window, 0); }); // 動畫函數 function animate(obj, target, callback) { // console.log(callback); callback = function() {} 調用的時候 callback() // 先清除以前的定時器,只保留當前的一個定時器執行 clearInterval(obj.timer); obj.timer = setInterval(function() { // 步長值寫到定時器的里面 // 把我們步長值改為整數 不要出現小數的問題 // var step = Math.ceil((target - obj.offsetLeft) / 10); var step = (target - window.pageYoffset) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if (window.pageYoffset == target) { // 停止動畫 本質是停止定時器 clearInterval(obj.timer); // 回調函數寫到定時器結束里面 // if (callback) { // // 調用函數 // callback(); // } // 注意此處的優化代碼 callback && callback(); } // 把每次加1 這個步長值改為一個慢慢變小的值 步長公式:(目標值 - 現在的位置) / 10 // obj.style.left = window.pageYoffset + step + 'px'; window.scroll(0, window.pageYoffset + step) }, 15); } </script>