如何開發一個用戶腳本系列(4)——腳本二:一個返回頂部和到達底部的按鈕

在這篇文章中,咱們將一塊兒學習腳本 一個返回頂部和到達底部的按鈕 的開發。在正式開始以前,先說一下我認爲開發腳本應該遵循的兩個準則:css

  • 功能實現。當你決定要開發一個腳本的時候,你確定清楚你的腳本要實現什麼功能,只有你的腳本實現了你所描述的功能,纔會有更多的人安裝使用,纔會有更多的人給你好評;
  • 樣式實現。什麼叫樣式實現?就是你在目標網站中添加的元素,要儘可能與原網站的配色,樣式相一致。這一項是非必須的,但我認爲是很是重要的。你想一想,若是原網站總體是藍色,而你添加的按鈕是紅色,那該有多突兀,有多醜,雖然你的按鈕確實突出了,但別人一看就是山寨,看着會很不舒服。而若是你的按鈕也用它網站的顏色,這樣就會跟原網站已有的元素契合,總體特別天然,作到以假亂真的效果。你的腳本讓別人用的舒服,別人才更願意給你好評。

需求分析

咱們在平時上網的時候會發現,不少網站在網站右下角提供了一個返回頂部的按鈕,當用戶向下瀏覽網頁時,該按鈕就會出現,而後點擊按鈕網頁就會滾動回到頂部,很是方便。可是有一部分網頁沒有提供這種按鈕,若是須要返回網頁頂部,就須要本身一點一點滾動,很不方便。同時,大多數網頁也並無提供一鍵到達網頁底部的功能。有人可能會問,咱們瀏覽網頁就是從上往下瀏覽,爲何還須要一鍵到達網頁底部?你要知道,你不須要不表明別人不須要,有些網頁底部有評論,或者有網站的一些入口,而別人並不想看網頁中的內容,只想趕快到達網頁底部看他想看的內容,這時候,這個按鈕就能提供方便。因此今天要作的,就是在網頁中添加一個按鈕,初始狀態下,該按鈕箭頭向下,當用戶點擊後,網頁就會快速滾動到底部,而後按鈕箭頭變爲向上,用戶再次點擊後,網頁又會快速滾動到頂部。而用戶在瀏覽網頁的過程當中,按鈕會根據用戶的瀏覽方向,自動變換箭頭方向,很是智能。好比說,用戶向下瀏覽網頁,按鈕箭頭會向下,用戶向上瀏覽網頁,按鈕箭頭會向上。html

功能實現

要實現上面的功能,咱們首先須要兩張按鈕箭頭的圖片。這裏感謝爲我切圖的 UI 小姐姐,我以爲她切的圖真漂亮。我把圖片放在個人 coding.net 倉庫,固然你放在任何一個能夠公開訪問到的地方均可以,而後咱們在腳本開頭用 @resource 引入咱們須要用到的圖片。而咱們在代碼中若是要使用圖片,還須要腳本管理器的 GM_getResourceURL() 函數,因此咱們使用 @grant 聲明。咱們但願咱們的按鈕在全部網站都生效,因此咱們用 @match 匹配全部網站。在腳本編寫過程當中會用到 jQuery,因此咱們使用 @require 引入 jQuery 庫。jquery

// @resource    up_button_icon    https://coding.net/u/mofiter/p/public_files/git/raw/master/back_to_top_button.png
// @resource    down_button_icon    https://coding.net/u/mofiter/p/public_files/git/raw/master/go_to_bottom_button.png
// @grant    GM_getResourceURL
// @match    *://*
// @require    https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js

準備工做作完以後,咱們開始編寫代碼。咱們但願咱們的按鈕固定在網頁右下角,距離底部 50px,距離右邊 30px,按鈕寬和高都爲 35px,按鈕默認顯示向下的箭頭,按鈕初始化透明度爲 0.5,當咱們將鼠標移入按鈕時,按鈕透明度變爲 0.8,有一個明暗變化使用體驗更好。git

var opacityMouseLeave = 0.5; //當鼠標不在按鈕上時,按鈕的不透明度,從 0.0(徹底透明)到 1.0(徹底不透明)
    var opacityMouseEnter = 0.8; //當鼠標在按鈕上時,按鈕的不透明度,從 0.0(徹底透明)到 1.0(徹底不透明)
    var goTopBottomButton = document.createElement("div");
    goTopBottomButton.className = "goTopBottomButton";
    goTopBottomButton.innerHTML = "<img class='toggleButton' style='width:35px;height:35px;display:block;cursor:pointer;'></img>"; //圖片的寬和高可修改,原始圖片寬高均爲 40px
    goTopBottomButton.style.position = "fixed"; // 按鈕位置固定
    goTopBottomButton.style.zIndex = 10000; // 按鈕堆疊順序,數字越大,越顯示在前面
    goTopBottomButton.style.bottom = "50px"; //距離網頁底部 50px
    goTopBottomButton.style.right = "30px"; //距離網頁右邊 30px
    var toggleButton = goTopBottomButton.lastChild;
    toggleButton.style.opacity = opacityMouseLeave; //按鈕初始不透明度
    toggleButton.src = GM_getResourceURL("down_button_icon"); //按鈕初始顯示向下的圖片
    document.getElementsByTagName("body")[0].appendChild(goTopBottomButton); // 將按鈕添加到網頁中

如今按鈕已經能夠正常加載出來了,下面咱們進行事件的處理。爲了讓用戶體驗更好,咱們添加了這樣一個功能。當鼠標放在按鈕上時,頁面會根據當前瀏覽方向自動滾動,這個功能是否開啓由變量 canScrollMouseOver 控制。當 canScrollMouseOver 爲 true 時,咱們判斷當前網頁滾動方向,若是用戶在向下瀏覽網頁,網頁將自動向下滾動,當用戶在向上瀏覽網頁時,網頁將自動向上滾動。這個滾動速度較慢,目的是爲了讓用戶能夠看得清。而當用戶點擊按鈕時,網頁將直接滾動到底部或頂部,這個滾動速度較快。當鼠標移出按鈕時,自動滾動將會中止。在向下滾動的時候,有可能會遇到這樣的問題。如今部分網頁採用動態加載數據的方式,當前網頁的全部數據並不會在網頁初次加載的時候所有請求,而是會在用戶向下瀏覽網頁的時候再去請求數據,這樣就會致使網頁高度發生變化,爲了不當點擊按鈕後出現無休止的向下滾動,因此須要添加變量來記錄網頁動態加載數據的次數,若是次數超過了咱們設置的最大次數,就應該中止向下滾動並告知用戶。app

var $ = window.$;
    var canScrollMouseOver = false; //當鼠標在按鈕上,但未點擊時,頁面可否自動滾動,true 爲能夠自動滾動,false 爲不能自動滾動
    var clickScrollTime = 500; //點擊按鈕時,網頁滾動到頂部或底部須要的時間,單位是毫秒
    var needScrollTime; //網頁能夠自動滾動時,滾動須要的時間,由網頁高度計算得出,這樣不一樣網頁都會勻速滾動
    var isClicked = false; //按鈕是否被點擊
    var initialHeight = 0; //網頁向底部滾動時,須要滾動的距離
    var scrollDirection = "down"; //網頁滾動方向,down 爲向下,up 爲向上
    var loadTimes = 0; //網頁中動態增長數據的次數
    var maxLoadTimes = 10; //最大的動態增長數據的次數,若是動態增長數據的次數超過這個值,則說明當前網頁不適合執行此腳本,建議將其加入排除的網站當中
    toggleButton.addEventListener("mouseenter",function() { //鼠標移入時不透明度改變,若是 canScrollMouseOver 爲 true,則網頁能夠自動滾動
        isClicked = false;
        if (canScrollMouseOver) {
            if (scrollDirection == "up") {
                needScrollTime = getScrollTop() * 10;
                $('html,body').animate({scrollTop:'0px'},needScrollTime);
            } else {
                initialHeight = $(document).height();
                var restHeight = $(document).height() - getScrollTop();
                needScrollTime = restHeight * 10;
                $('html,body').animate({scrollTop:initialHeight},needScrollTime,continueToBottom);
            }
        }
        toggleButton.style.opacity = opacityMouseEnter;
    })
    toggleButton.addEventListener("mouseleave",function() { //鼠標移出時不透明度改變,若是 canScrollMouseOver 爲 true,而且按鈕未被點擊,中止網頁自動滾動的動畫
        if (canScrollMouseOver && !isClicked) {
            $('html,body').stop();
        }
        toggleButton.style.opacity = opacityMouseLeave;
    })
    toggleButton.addEventListener("click",function() { //點擊按鈕時,網頁滾動到頂部或底部
        isClicked = true;
        if (canScrollMouseOver) {
            $('html,body').stop();
        }
        if (scrollDirection == "up") {
            $('html,body').animate({scrollTop:'0px'},clickScrollTime);
        } else {
            initialHeight = $(document).height();
            $('html,body').animate({scrollTop:initialHeight},clickScrollTime,continueToBottom);
        }
    })
    function getScrollTop() { //獲取垂直方向滑動距離
        var scrollTop = 0;
        if (document.documentElement && document.documentElement.scrollTop) {
            scrollTop = document.documentElement.scrollTop;
        } else if (document.body) {
            scrollTop = document.body.scrollTop;
        }
        return scrollTop;
    }
    function continueToBottom() { //判斷頁面是否繼續下滑(主要是爲了處理網頁動態增長數據致使網頁高度變化的狀況)
        var currentHeight = $(document).height();
        if (initialHeight != currentHeight) {
            if (loadTimes >= maxLoadTimes) {
                $('html,body').stop();
                alert(" 本網站有太多的異步請求,不適合執行腳本《" + GM_info.script.name + "》,建議加入排除網站當中,具體方法請查看腳本主頁");
                loadTimes = 0;
                return;
            }
            loadTimes ++;
            initialHeight = currentHeight;
            $('html,body').animate({scrollTop:initialHeight},1000,continueToBottom);
        }
    }

如今當你將鼠標放在按鈕上和從按鈕上移出時,按鈕透明度會變化。而且,若是你的變量 canScrollMouseOver 爲 true,那麼網頁也會自動向下滾動。下面咱們要對網頁滾動方向進行監聽,若是網頁向下滾動,或者網頁滾動到了頂部,則按鈕顯示向下箭頭,若是網頁向上滾動,或者網頁滾動到了底部,則按鈕顯示向上箭頭。異步

var scrollAction = 'undefined';
    document.onscroll = function() {
        if (scrollAction == 'undefined') {
            scrollAction = window.pageYOffset;
        }
        var diffY = scrollAction - window.pageYOffset;
        scrollAction = window.pageYOffset;
        if (diffY < 0) {
            changeDirection("down");
        } else if (diffY > 0) {
            changeDirection("up");
        }
        if (getScrollTop() == 0) {
            changeDirection("down");
        }
        if (getScrollTop() + $(window).height() >= $(document).height()) {
            changeDirection("up");
        }
    }
    function changeDirection(direction) { //改變按鈕方向
        scrollDirection = direction;
        toggleButton.src = GM_getResourceURL(direction + "_button_icon");
    }

至此,咱們就完成了這個腳本的開發,至於發佈腳本的流程能夠參考上一篇文章 如何開發一個用戶腳本系列(3)——腳本一:百度首頁和搜索頁面添加 Google 搜索框函數

總結

本文對腳本 一個返回頂部和到達底部的按鈕 的開發過程進行了介紹,若是還有疑問,能夠留言,下一篇文章將對腳本 網易雲課堂下載助手 的開發過程進行介紹。學習

相關文章
相關標籤/搜索