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后面引入。

效果如下:

image

点击按钮后,页面滚回到顶部。

矢量图标

与老版本不同,Bootstrap 4 中也没有自带图标。作为补偿,官方也推荐了几款强大且免费的第三方矢量图标提供商。我比较喜欢的是Font Awesome,提供1500+免费图标(以及5000+付费图标),完全够用了。各种你想得到想不到的图标都有:

image

用法也很简单,你甚至不用将其下载到本地(当然想下载也可以)。根据官网的提示,直接在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

image

点击图标进去后就能看到它的标签名称

image

将此标签名称复制到你的网页中,图标就渲染出来了。

很神奇的是,矢量图标跟普通的字体是完全类似的,你可以通过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>
...

看看效果:

image

好玩吧。读者朋友慢慢挑选心仪的图标,到自己的博客中吧。

相比写代码来说,这是个相当愉悦的过程。

页脚沉底

刚才做浮动按钮时,取消了页脚固定在底部的fixed-bottom

按钮倒是没被遮盖了,但又冒出来另一个烦人的问题,请看下图:

image

当页面内容较少时,页脚下方居然空出来一大块地方,太丑了。

《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的空白罢了。

刷新页面:

image

舒服了。

随着项目逐渐增大,HTML、JavaScript、CSS交织在一起,也更加混乱。

虽然教程没有把这三种类型的代码分离开,但是你应该考虑这样做。

粘性侧边栏

目前教程将文章目录放置在文章的右侧,这就是相当于是个侧边栏。问题是当用户向下阅读文章时,目录却不会固定在页面中,而是几下就翻得没影了,影响体验。

粘性侧边栏就是来解决这个问题的。当页面向下滚动时,粘性侧边栏会灵活的固定在屏幕中,保证用户在任何位置都可以看到侧边栏中的内容。

具体工作模式如下图:

image

考虑到侧边栏有可能会很长,因此设计出足够“聪明”的粘性侧边栏也不那么容易。教程将用到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 %}中,否则会报错哦。

插件还有其他可设置的规则,详情见官方文档

刷新页面,不管你怎么滚动页面,目录都显示在屏幕中,并且随着滚轮很自然的上下移动了:

image

总结

本章学习了回到顶部浮动按钮、矢量图标、页脚沉底和粘性侧边栏四个功能。

就像前面说的,这几个功能跟Django没什么关系,但是既然要想做一个完整的博客网站,就不要抱有幻想。光靠那么一点点Django代码是不可能的,什么知识你都得会一点才行。

读者以后会遇到更加多样的编程工具,一定不要被“Django程序员”这个头衔所束缚,勇敢去学吧。谁让你已经上了贼船呢。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容

  • Android UI相关开源项目库汇总OpenDigg 抽屉菜单MaterialDrawer ★7337 - 安卓...
    黄海佳阅读 8,699评论 3 77
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,734评论 1 92
  • 文/一夜知秋朵 时光飞逝,惊鸿一瞥,转眼之间我们90后的一代,也陆续的到了闯荡社会的年纪。 最早的90后一代也已经...
    一夜知秋朵阅读 319评论 0 1
  • 1989年8月,随着家里最小的妹妹接到大学录取通知书,父亲曾经规划的"五子登科"的宏伟蓝图,经过我们兄弟姊妹十...
    旭_f7f5阅读 218评论 0 1
  • 这是一些我个人自己的想法,如果大家有不同的看法可以提出来^_^,让我们的思想在音乐的旋律中产生共鸣。 1.The ...
    佾叶阅读 388评论 0 3