文章出處

前面的話

  本文先詳細介紹回到頂部的5種寫法,然后對其實現功能增加,最后得到最終實現

 

寫法

【1】錨點

  使用錨點鏈接是一種簡單的返回頂部的功能實現。該實現主要在頁面頂部放置一個指定名稱的錨點鏈接,然后在頁面下方放置一個返回到該錨點的鏈接,用戶點擊該鏈接即可返回到該錨點所在的頂部位置

  [注意]關于錨點的詳細信息移步至此

<body style="height:2000px;">
    <div id="topAnchor"></div>
    <a href="#topAnchor" style="position:fixed;right:0;bottom:0">回到頂部</a>
</body>

【2】scrollTop

  scrollTop屬性表示被隱藏在內容區域上方的像素數。元素未滾動時,scrollTop的值為0,如果元素被垂直滾動了,scrollTop的值大于0,且表示元素上方不可見內容的像素寬度

  由于scrollTop是可寫的,可以利用scrollTop來實現回到頂部的功能

  [注意]關于頁面的scrollTop的兼容問題詳細內容移步至此

<body style="height:2000px;">
    <button id="test" style="position:fixed;right:0;bottom:0">回到頂部</button>
    <script>
        test.onclick = function(){
            document.body.scrollTop = document.documentElement.scrollTop = 0;
        }
    </script>
</body>

【3】scrollTo()

  scrollTo(x,y)方法滾動當前window中顯示的文檔,讓文檔中由坐標x和y指定的點位于顯示區域的左上角

  設置scrollTo(0,0)可以實現回到頂部的效果

<body style="height:2000px;">
    <button id="test" style="position:fixed;right:0;bottom:0">回到頂部</button>
    <script>
        test.onclick = function(){
            scrollTo(0,0);
        }
    </script>
</body>

【4】scrollBy()

  scrollBy(x,y)方法滾動當前window中顯示的文檔,x和y指定滾動的相對量

  只要把當前頁面的滾動長度作為參數,逆向滾動,則可以實現回到頂部的效果

<body style="height:2000px;">
    <button id="test" style="position:fixed;right:0;bottom:0">回到頂部</button>
    <script>
        test.onclick = function(){
            var top = document.body.scrollTop || document.documentElement.scrollTop
            scrollBy(0,-top);
        }
    </script>
</body>

【5】scrollIntoView()

  Element.scrollIntoView方法滾動當前元素,進入瀏覽器的可見區域 

  該方法可以接受一個布爾值作為參數。如果為true,表示元素的頂部與當前區域的可見部分的頂部對齊(前提是當前區域可滾動);如果為false,表示元素的底部與當前區域的可見部分的尾部對齊(前提是當前區域可滾動)。如果沒有提供該參數,默認為true

  使用該方法的原理與使用錨點的原理類似,在頁面最上方設置目標元素,當頁面滾動時,目標元素被滾動到頁面區域以外,點擊回到頂部按鈕,使目標元素重新回到原來位置,則達到預期效果

<body style="height:2000px;">
    <div id="target"></div>
    <button id="test" style="position:fixed;right:0;bottom:0">回到頂部</button>
    <script>
        test.onclick = function(){
            target.scrollIntoView();
        }
    </script>
</body>

增強

  下面對回到頂部的功能進行增強

【1】顯示增強

  使用CSS畫圖,將“回到頂部”變成可視化的圖形(如果兼容IE8-瀏覽器,則用圖片代替)

  使用CSS偽元素偽類hover效果,當鼠標移動到該元素上時,顯示回到頂部的文字,移出時不顯示  

<style>
.box{
    position:fixed;
    right:10px;
    bottom: 10px;
    height:30px;
    width: 50px;    
    text-align:center;
    padding-top:20px;    
    background-color: lightblue;
    border-radius: 20%;
    overflow: hidden;
}
.box:hover:before{
    top:50%
}
.box:hover .box-in{
    visibility: hidden;
}
.box:before{
    position: absolute;
    top: -50%;
    left: 50%;
    transform: translate(-50%,-50%);
    content:'回到頂部';
    width: 40px;
    color:peru;
    font-weight:bold;

}    
.box-in{
    visibility: visible;
    display:inline-block;
    height:20px;
    width: 20px;
    border: 3px solid black;
    border-color: white transparent transparent white;
    transform:rotate(45deg);
}
</style>

<body style="height:2000px;">
<div id="box" class="box">
    <div class="box-in"></div>
</div>    
</body>

【2】動畫增強

  為回到頂部增加動畫效果,滾動條以一定的速度回滾到頂部

  動畫有兩種:一種是CSS動畫,需要有樣式變化配合transition;一種是javascript動畫,使用定時器來實現  

  在上面的5種實現中,scrollTop、scrollTo()和scrollBy()方法可以增加動畫,且由于無樣式變化,只能增加javascript動畫

  定時器又有setIntervalsetTimeoutrequestAnimationFrame這三種可以使用,下面使用性能最好的定時器requestAnimationFrame來實現

  [注意]IE9-瀏覽器不支持該方法,可以使用setTimeout來兼容

  1、增加scrollTop的動畫效果

  使用定時器,將scrollTop的值每次減少50,直到減少到0,則動畫完畢

<script>
var timer  = null;
box.onclick = function(){
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if(oTop > 0){
            document.body.scrollTop = document.documentElement.scrollTop = oTop - 50;
            timer = requestAnimationFrame(fn);
        }else{
            cancelAnimationFrame(timer);
        }    
    });
}
</script>

 【時間版運動】

  但是,上面的代碼有一個問題,就是當頁面內容較多時,回到頂部的動畫效果將持續很長時間。因此,使用時間版的運動更為合適,假設回到頂部的動畫效果共運動500ms,則代碼如下所示

<body style="height: 2000px;">
<button id="test" style="position:fixed;right:10px;bottom:10px;">回到頂部</button>
<script>
var timer  = null;
test.onclick = function(){
    cancelAnimationFrame(timer);
    //獲取當前毫秒數
    var startTime = +new Date();     
    //獲取當前頁面的滾動高度
    var b = document.body.scrollTop || document.documentElement.scrollTop;
    var d = 500;
    var c = b;
    timer = requestAnimationFrame(function func(){
        var t = d - Math.max(0,startTime - (+new Date()) + d);
        document.documentElement.scrollTop = document.body.scrollTop = t * (-c) / d + b;
        timer = requestAnimationFrame(func);
        if(t == d){
          cancelAnimationFrame(timer);
        }
    });
}
</script>
</body>

  2、增加scrollTo()動畫效果

  將scrollTo(x,y)中的y參數通過scrollTop值獲取,每次減少50,直到減少到0,則動畫完畢

<script>
var timer  = null;
box.onclick = function(){
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if(oTop > 0){
            scrollTo(0,oTop-50);
            timer = requestAnimationFrame(fn);
        }else{
            cancelAnimationFrame(timer);
        }    
    });
}
</script>

  3、增加scrollBy()動畫效果

  將scrollBy(x,y)中的y參數設置為-50,直到scrollTop為0,則回滾停止

<script>
var timer  = null;
box.onclick = function(){
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if(oTop > 0){
            scrollBy(0,-50);
            timer = requestAnimationFrame(fn);
        }else{
            cancelAnimationFrame(timer);
        }    
    });
}
</script>

 

實現

  由于scrollTop、scrollBy()和scrollTo()方法,都以scrollTop值是否減少為0作為動畫停止的參照,且三個動畫的原理和實現都基本相似,性能也相似。最終,以最常用的scrollTop屬性實現動畫增強效果

  當然,如果覺得500ms的時間不合適,可以根據實際情況進行調整

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.box{
    position:fixed;
    right:10px;
    bottom: 10px;
    height:30px;
    width: 50px;    
    text-align:center;
    padding-top:20px;    
    background-color: lightblue;
    border-radius: 20%;
    overflow: hidden;
}
.box:hover:before{
    top:50%
}
.box:hover .box-in{
    visibility: hidden;
}
.box:before{
    position: absolute;
    top: -50%;
    left: 50%;
    transform: translate(-50%,-50%);
    content:'回到頂部';
    width: 40px;
    color:peru;
    font-weight:bold;

}    
.box-in{
    visibility: visible;
    display:inline-block;
    height:20px;
    width: 20px;
    border: 3px solid black;
    border-color: white transparent transparent white;
    transform:rotate(45deg);
}
</style>
</head>
<body style="height:2000px;">
<div id="box" class="box">
    <div class="box-in"></div>
</div>    
<script>
var timer  = null;
box.onclick = function(){
    cancelAnimationFrame(timer);
    //獲取當前毫秒數
    var startTime = +new Date();     
    //獲取當前頁面的滾動高度
    var b = document.body.scrollTop || document.documentElement.scrollTop;
    var d = 500;
    var c = b;
    timer = requestAnimationFrame(function func(){
        var t = d - Math.max(0,startTime - (+new Date()) + d);
        document.documentElement.scrollTop = document.body.scrollTop = t * (-c) / d + b;
        timer = requestAnimationFrame(func);
        if(t == d){
          cancelAnimationFrame(timer);
        }
    });
}
</script>
</body>
</html>

  歡迎交流


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()