Django搭建個人博客:回到頂部浮動按鈕、矢量圖標、頁腳沉底和粘性側邊欄

本章集中介紹四個重要的小功能:回到頂部浮動按鈕矢量圖標頁腳沉底粘性側邊欄

這幾個功能與Django基本沒啥關係,更多的是前端知識,但是對博客網站都很重要,問的讀者也比較多,因此也集中講一下好了。

回到頂部浮動按鈕

當用戶拜讀完你的博文後,可能想回到文章開頭重新閱讀,或者審視其中的某些內容。如果文章內容較多,不停滑動滾輪迴頁面頂部未免有點太讓人煩躁了。

一種解決辦法是增加一個回到頂部的浮動按鈕。當頁面向下滾動到某個位置後,按鈕就呈現在頁面右下角;點擊按鈕,頁面就回到頂部。這個功能 Bootstrap 4 似乎沒有提供,但也不復雜,就自己用 JavaScript 和 CSS 寫吧。

templates目錄新建back_to_top_func.html文件,寫入以下代碼:

templates/back_to_top_func.html

<!-- 參考了 鸚鵡 的代碼,在此致謝 -->
<!-- https://ezbox.idv.tw/131/back-to-top-button-without-images -->

<button type="button" id="BackTop" class="toTop-arrow" style="z-index: 100;"></button>

<script>
    // 向上滾動的函數
    $(function () {
        $('#BackTop').click(function () {
            $('html,body').animate({scrollTop: 0}, 500);
        });
        $(window).scroll(function () {
            if ($(this).scrollTop() > 300) {
                $('#BackTop').fadeIn(300);
            } else {
                $('#BackTop').stop().fadeOut(300);
            }
        }).scroll();
    });
</script>

<style>
    /* 按鈕邊框的大小、位置、樣式 */
    .toTop-arrow {
        width: 3.5rem;
        height: 3.5rem;
        padding: 0;
        margin: 0;
        border: 0;
        border-radius: 33%;
        opacity: 0.7;
        background: black;
        cursor: pointer;
        position: fixed;
        right: 1.5rem;
        bottom: 1.5rem;
        display: none;
    }

    /* 繪製按鈕中的向上箭頭 */
    .toTop-arrow::before, .toTop-arrow::after {
        width: 31px;
        height: 7px;
        border-radius: 3px;
        background: orange;
        position: absolute;
        content: "";
    }

    .toTop-arrow::before {
        transform: rotate(-45deg) translate(0, -50%);
        left: 0.4rem;
    }

    .toTop-arrow::after {
        transform: rotate(45deg) translate(0, -50%);
        right: 0.4rem;
    }

    /* 取消點擊按鈕時的聚焦 */
    .toTop-arrow:focus {
        outline: none;
    }
</style>

代碼分成htmljavascriptcss三部分。

HTML部分只有一行,用button標籤表示了浮動按鈕的容器。

JavaScript部分主要用到了Jquery的語法。頁面加載完成後開始監聽兩個事件:

  • 當用戶點擊浮動按鈕時,將頁面滾動到頂部
  • 當頁面滾動時,根據頁面距離頂部的距離,決定按鈕顯示或隱藏

CSS部分最長但也很簡單,主要定義了按鈕的位置、大小、圖案等樣式。讀者可以試着、改動、刪除部分代碼,看看按鈕形態會怎樣變化。

核心代碼就寫好了。有點小瑕疵的是前面在footer.html中定義了class="fixed-bottom",這個屬性的顯示層級很高,會將浮動按鈕給覆蓋掉。因此刪除templates/footer.html中的fixed-bottom屬性:

templates/footer.html

...
<!-- 刪除了 fixed-bottom 屬性 -->
<footer class="py-3 bg-dark">
    ...
</footer>

z-index這個css樣式決定了頁面中容器的顯示順序,數值越大則顯示優先級越高。

之所以fixed-bottom會覆蓋掉浮動按鈕,就是因爲它將z-index設置成了一個很大的數值。

因爲我們想在全站都擁有這個按鈕,所以將剛寫好的模塊引用到base.html中:

templates/base.html

...

<body>
    ...

    <!-- jquery.js -->
    <script src="{% static 'jquery/jquery-3.3.1.js' %}"></script>
    ...
    <!-- 在jquery後面引入 -->
    {% include 'back_to_top_func.html' %}

</body>
...

注意模塊用到了Jquery,因此要在Jquery後面引入。

效果如下:

點擊按鈕後,頁面滾回到頂部。

矢量圖標

與老版本不同,Bootstrap 4 中也沒有自帶圖標。作爲補償,官方也推薦了幾款強大且免費的第三方矢量圖標提供商。我比較喜歡的是Font Awesome,提供1500+免費圖標(以及5000+付費圖標),完全夠用了。各種你想得到想不到的圖標都有:

用法也很簡單,你甚至不用將其下載到本地(當然想下載也可以)。根據官網的提示,直接在base.html中引入:

templates/base.html

...
<link rel="stylesheet" 
      href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" 
      integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" 
      crossorigin="anonymous"
>
...

然後在頁面中插入某個圖標的標籤就可以用了。

首先在官網圖標庫搜索想要的圖標,比如eye

點擊圖標進去後就能看到它的標籤名稱

將此標籤名稱複製到你的網頁中,圖標就渲染出來了。

很神奇的是,矢量圖標跟普通的字體是完全類似的,你可以通過CSS定義圖標的顏色(color)、大小(font-size)等樣式。

嘗試一下。將圖標代碼添加到templates/article/list.html中的列表循環:

templates/article/list.html

...
<!-- 註腳 -->
<p>
    <!-- 附加信息,增加了圖標 -->
    <span>
        <i class="fas fa-eye" style="color: lightskyblue;"></i>
        {{ article.total_views }}&nbsp;&nbsp;&nbsp;
    </span>
    <span>
        <i class="fas fa-comments" style="color: yellowgreen;"></i>
        <!-- 修改爲評論的計數 -->
        {{ article.comments.count }}&nbsp;&nbsp;&nbsp;
    </span>
    <span>
        <i class="fas fa-clock" style="color: pink;"></i>
        {{ article.created|date:'Y-m-d' }}
    </span>
</p>
...

看看效果:

好玩吧。讀者朋友慢慢挑選心儀的圖標,到自己的博客中吧。

相比寫代碼來說,這是個相當愉悅的過程。

頁腳沉底

剛纔做浮動按鈕時,取消了頁腳固定在底部的fixed-bottom

按鈕倒是沒被遮蓋了,但又冒出來另一個煩人的問題,請看下圖:

當頁面內容較少時,頁腳下方居然空出來一大塊地方,太醜了。

《Sticky Footer, Five Ways》羅列了5種方法解決這個問題,有興趣的同學可深入瞭解。

需要修改base.htmlfooter.html兩個文件。先貼改動代碼:

templates/base.html

...
<body>
    {% include 'header.html' %}
    
    <!-- 新增兩個 div 容器 -->
    <div id="wrapper">
        {% block content %}{% endblock content %}
        <div id="push"></div>
    </div>

    {% include 'footer.html' %}

    ...
    
    <!-- 增加樣式 -->
    <style>
        html, body {
            height: 100%;
            margin: 0;
        }

        #wrapper {
            min-height: 100%;
            margin-bottom: -60px;
        }

        #footer,
        #push {
            height: 60px;
        }
    </style>
    
</body>
...
templates/footer.html

...
<!-- 增加 id="footer" 屬性 -->
<footer ... id="footer">
    ...
</footer>

代碼通過CSS樣式控制頁面尺寸不小於屏幕的高度,以及頁腳的高度爲60px。不太好理解的主要有兩個地方:

  • #push容器留出一段與頁腳等高的空隙,避免正文內容與頁腳重疊。
  • #wrapper容器的底部有一個負邊距,作用是給頁腳容器讓出位置。這個負邊距你不設置也可以,無非就是底部多出高度爲60px的空白罷了。

刷新頁面:

舒服了。

隨着項目逐漸增大,HTML、JavaScript、CSS交織在一起,也更加混亂。

雖然教程沒有把這三種類型的代碼分離開,但是你應該考慮這樣做。

粘性側邊欄

目前教程將文章目錄放置在文章的右側,這就是相當於是個側邊欄。問題是當用戶向下閱讀文章時,目錄卻不會固定在頁面中,而是幾下就翻得沒影了,影響體驗。

粘性側邊欄就是來解決這個問題的。當頁面向下滾動時,粘性側邊欄會靈活的固定在屏幕中,保證用戶在任何位置都可以看到側邊欄中的內容。

具體工作模式如下圖:

考慮到側邊欄有可能會很長,因此設計出足夠“聰明”的粘性側邊欄也不那麼容易。教程將用到Abouolia粘性側邊欄插件,強大且小巧,讀者可以去官方示例感受一下。

插件的GitHub庫下載到本地後,因爲博客項目已經加載好了Jquery,所以只需要用到dist目錄下的jquery.sticky-sidebar.min.js這個文件就可以了。在項目的static目錄下新建目錄sticky_sidebar,將其粘貼進去:

/static/sticky_sidebar/jquery.sticky-sidebar.min.js

因爲只需要在文章詳情頁面用到,所以在詳情頁中引入模塊就夠用了:

templates/article/detail.html

...
<!-- 目錄 -->
<div ... id="sidebar" class="sidebar">
    <div class="sidebar__inner">
        <h4><strong>目錄</strong></h4>
        <hr>
        <div>
            {{ toc|safe }}
        </div>
    </div>
</div>

...

<!-- 粘性側邊欄樣式 -->
<style>
    .sidebar{
        will-change: min-height;
    }

    .sidebar__inner{
        transform: translate(0, 0);
        transform: translate3d(0, 0, 0);
        will-change: position, transform;
    }
</style>

...

{% block script %}
<!-- 引入粘性側邊欄 -->
<script src="{% static 'sticky_sidebar/jquery.sticky-sidebar.min.js' %}"></script>
<script type="text/javascript">
    $('#sidebar').stickySidebar({
        topSpacing: 20,
        bottomSpacing: 20,
    });
</script>

...
{% endblock script %}

按照插件的要求,側邊欄套上了兩層容器,第一層含有屬性id="sidebar" class="sidebar",第二層含有屬性class="sidebar__inner"。然後設置樣式,引入靜態文件並調用插件,沒什麼好說的,照做就可以了。與前面的章節相同,由於插件需求Jquery,一定要把 JavaScript 語句放到{% block script %}中,否則會報錯哦。

插件還有其他可設置的規則,詳情見官方文檔

刷新頁面,不管你怎麼滾動頁面,目錄都顯示在屏幕中,並且隨着滾輪很自然的上下移動了:

總結

本章學習了回到頂部浮動按鈕、矢量圖標、頁腳沉底和粘性側邊欄四個功能。

就像前面說的,這幾個功能跟Django沒什麼關係,但是既然要想做一個完整的博客網站,就不要抱有幻想。光靠那麼一點點Django代碼是不可能的,什麼知識你都得會一點才行。

讀者以後會遇到更加多樣的編程工具,一定不要被“Django程序員”這個頭銜所束縛,勇敢去學吧。誰讓你已經上了賊船呢。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章