给自己的随笔加一个好看的(并不)导航列表

前言

  由于本人学新技术时,喜欢把所有相关知识堆在一块,经常文章过长,想要定位到某一特定知识点时非常不方便,因此想着给长随笔加一个导航链接。一开始没明白博客园自定义样式的工作原理,吭哧吭哧把代码码好,发布出去一看,WTF,样式不对啊,这么丑的东西才不是我写的。

  赶紧打开F12,一看,原来是博客园本身的样式覆盖了我的自定义属性,知道原因事情就好(并)办(没)了(有)。

  总之,经过一番艰辛的尝试后,一个还算可以的导航列表总算是大功告成,为了纪念一下这个令人高兴的时刻,应该写点什么。话不多说,马上开始正片。

你需要预先了解的知识

  由于本人设计经验非常有限,并且组件只到1.0版本,所以也没用到什么高深的技术,你只需要了解HTML和CSS就行,最好也能了解CSS3。

准备阶段

  首先,你需要分析,哪些标题需要显示在列表中,将它们按照标题的级别(h1~h6)分层排列。

  然后,将标题按照导航列表模板进行嵌套,以下是我的模板:

<ul class="nav-list">
  <!--  这里是一级列表项,对应于你最高一级的标题,倒不一定都是h1,这个看个人发挥  -->
  <li class="nav-list-li"><a href="#目标标题">一级列表项</a></li>
  <li class="nav-list-li"><a href="#目标标题">一级列表项</a></li>
  <li class="nav-list-li"><a href="#目标标题">一级列表项</a></li>
  <li class="nav-list-li"><a href="#目标标题">一级列表项</a></li>
   
  <li class="nav-list-li">
    <a href="#目标标题">一级列表项</a>
    <!--  这里是二级列表,你可以嵌套更多层,但尽量不要超过3层,否则会太丑。是的,就是丑,这是最不能忍的,不然还有什么意思。  -->
    <ul class="nav-list">
      <li><a href="#目标标题">二级列表项</a></li>
      <li><a href="#目标标题">二级列表项</a></li>
      <li><a href="#目标标题">二级列表项</a></li>
      <li><a href="#目标标题">二级列表项</a></li>
    </ul>
  </li>
</ul>

------------------------------------------------------------我是一条分界线---------------------------------------------------------------

  接下来是重点,为列表添加一套自己的样式,以下是我的样式表:

<style>
    /*导航列表*/
    .nav-list {
        position: fixed!important;
        top: 50%!important;
        right: 0!important; 
        height: 276px!important;
        margin: -143px -20px -20px 0!important;
        padding: 0  20px 0 0!important;
        border: 1px solid #e5e5e5!important;
        overflow: auto!important;
        -moz-border-radius: 6px!important;
        -webkit-border-radius: 6px!important;
        -o-border-radius: 6px!important;
        border-radius: 6px!important;
        font-size: 14px!important;
        visibility: hidden;/*为避免网速较慢时会看到本应隐藏的导航列表,直接将其默认设置为隐藏*/
    }
    /*显示导航列表,配合JS,实现当前位置距离页面顶部一定距离后才显示*/
    .show {
        visibility: visible;
    }
    /*所有列表项*/
    .nav-list li {
        list-style: none!important;
    }
    /*链接*/
    .nav-list a {
        border-top: 1px solid #F5F5F5!important;
        border-bottom: 1px solid #F5F5F5!important;
        margin-top: -1px!important;
        padding: 10px!important;
        text-decoration: none!important;
        display: block!important;
        color: #2589BB!important;
        opacity: 0.5!important;
    }
    .nav-list a:link {
        background-color: transparent;
    }
    .nav-list a:visited {
        background-color: #57B8ED;
        color: #005580;
    }
    .nav-list a:hover {
        background-color: #F5F5F5;
        color: #005580;
    }
    .nav-list a:active {
        background-color: #57B8ED;
        color: #005580;
    }
    /*导航列表一级列表项*/
    .nav-list-li>a{
        border-top: 1px solid #e5e5e5;
        border-bottom: 1px solid #e5e5e5;
        opacity: 0.7;
    }
    /*二级、三级以及更深层次的子列表*/
    .nav-list ul {
        margin-left: 10px!important;
        overflow: hidden!important;
        margin-bottom: 0!important;
    }

    /*注意*/
    .alert {
        color: red;
    }
</style>

  简单的解析:根据代码中绿色文字分隔不同的步骤(字多不看的请忽略这一段)

  第一步:为最外层容器设置样式,包括容器的位置、高度、边框。我这里是固定到窗口右侧,垂直居中;自动根据列表项的多少滚动显示隐藏内容;设置边框以及圆角

  第二步:统一去除列表项前面的小圆点

  第三步:为链接添加文字颜色,无背景色,上下边框(左右无),去除链接的下划线,让链接充满父元素宽度,并设置透明度;然后是l-v-h-a大法,改链接文字的颜色、背景色和透明度(透明度显示的效果可能肉眼区别不大)

  第四步:为二级(以及更下面的子列表)设置偏移量,请根据喜好酌情添加;以及设置当元素溢出时隐藏溢出部分:overflow:hidden,这一步是为后面设置列表项的边框做准备

  关于每一行代码后面的!important,作用是强制覆盖他人设定的样式(自己设定的有可能会被写在下面的样式覆盖),这是由于CSS样式有着“权重”这一概念,就算是写在下面的代码,同样有可能因为权重不够而被覆盖,此方法可以直接提升样式优先级为最高(比用户在浏览器中直接修改还是要低的),方便不是很了解CSS语言的小伙伴使用;对于在前端方面有所涉猎或者比较熟悉的小伙伴,可以按需添加或删除!important,毕竟这个方法并不是十分完美。

  这一阶段,有能力的小伙伴可以自己到浏览器里调试,改出想要的样式后再记录下来。

-------------------------------------------------------------我也是一条分界线--------------------------------------------------------------

  接下来是JS部分,实现滚动条距离页面顶部一定距离后显示导航列表,而未达到时默认隐藏的效果。做这个效果是因为我现在的博客使用的是博客园默认的CSS样式,右侧的侧边栏都是贴着窗口右边缘且数量较多,不隐藏的话,会在一进去页面时遮挡部分内容,不够美观。

function DiaplayNavList($navList, top) {
    this.$window = $(window),//window对象的jQuery化
    this.$navList = $navList,//你的导航列表的ID,jQuery化
    this.top = top || 0,//滚动条距离页面顶部的距离
    this.init = function() {//初始化导航列表
        this.displayNavList(this.$navList, this.top);
        this.scroll();
    },
    this.displayNavList = function(){
        //大于规定的距离后显示
        if(this.$window.scrollTop()>=top) {
            this.$navList.addClass('show');
        }else {//否则隐藏
            this.$navList.removeClass('show');
        }
    },
    this.scroll = function() {
        //保存this对象的引用,
        //使self指向DisplayNavList的实例,
        //以便在内嵌方法中使用
        var self = this;
        this.$window.scroll(function(){
            self.displayNavList(self.$navList, self.top);
        });
    }
}
(function() {//IIFE实例化DisplayNavList对象并初始化
    var $navList = $('#my-nav-list');
    var myNavList = new DiaplayNavList($navList, 1900);
    myNavList.init();
})();

  简单的解析:首先,创建一个JS的“类”(注意区别于其他面向对象语言的“类”概念),赋予它一些必要的属性和方法;然后使用IIFE实例化该类的一个对象,并将其初始化。具体每一步的目的请看绿色注释。

  关于为什么在文件里直接实例化对象,而不是将文件作为模块,然后在具体的页面中插入JS做实例化,是因为直接插入后我的代码变成了下面这样:

<script type="text/javascript">// <![CDATA[
var $navList = $('#my-nav-list');
var myNavList = new DiaplayNavList($navList, 1900);
myNavList.init();
// ]]></script>

博客园默认添加了// <![CDATA[......

// ]]>的注释,将JS代码完全注释掉了,也就相当于没写这段代码,暂时不知道要怎么避免这个机制,所有将实例化与模块直接放在了一起。

使用代码

  做完准备工作,接下来就是最关键的上传代码了。HTML可以直接打开相应随笔的编辑页面,点击编辑HTML源代码按钮,然后直接粘贴到最下面。

  CSS由于是通用样式,可以一起粘贴到源代码里,或者统一保存在个人设置的自定义样式区。

  而JS因为上面提到的问题,无法直接使用,也为了更加符合模块化的要求,将JS作为单独的文件上传到博客园的个人文件系统中。位置在个人主页“管理”标签->“文件”标签,选择好文件后上传。

  当然还需要在页面中进行引用,此案例中的引用为

<script type="text/javascript" src="https://files.cnblogs.com/files/cjc917/displayNavList.js"></script>

  引用你自己的文件时仅需要修改src属性为"https://files.cnblogs.com/files/你的用户名/文件名.js即可。

  至此,自定义导航列表组件大功告成,撒花❀❀❀❀

注意:由于我的设计里列表是半透明的,因此当列表正好处于公告栏上方时,会有些看不清列表项的文字。此时建议给列表添加背景色,并将透明度调高(最高位1,不透明;最低为0,完全透明)。当然,也可以像上面那样JS动态隐藏和显示。另外,有些小伙伴可能权限不够,而导致样式不能正常加载,可以尝试与工作人员交流,开通相应权限。

  如果有需要更多更好看样式的小伙伴,可以自行研究和开发,例如将二级列表隐藏,鼠标悬浮或点击后展开等。添加JavaScript还可以给列表增加更多神奇的功能。

原文地址:https://www.cnblogs.com/cjc917/p/7419676.html