给自己的随笔加一个好看的(并不)导航列表
前言
由于本人学新技术时,喜欢把所有相关知识堆在一块,经常文章过长,想要定位到某一特定知识点时非常不方便,因此想着给长随笔加一个导航链接。一开始没明白博客园自定义样式的工作原理,吭哧吭哧把代码码好,发布出去一看,WTF,样式不对啊,这么丑的东西才不是我写的。
赶紧打开F12,一看,原来是博客园本身的样式覆盖了我的自定义属性,知道原因事情就好(并)办(没)了(有)。
总之,经过一番艰辛的尝试后,一个还算可以的导航列表总算是大功告成,为了纪念一下这个令人高兴的时刻,应该写点什么。话不多说,马上开始正片。
你需要预先了解的知识
由于本人设计经验非常有限,并且组件只到1.0版本,所以也没用到什么高深的技术,你只需要了解HTML和CSS就行,最好也能了解CSS3。
准备阶段
首先,你需要分析,哪些标题需要显示在列表中,将它们按照标题的级别(h1~h6)分层排列。
然后,将标题按照导航列表模板进行嵌套,以下是我的模板:
<ul class="nav-list"> <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> <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>
------------------------------------------------------------我是一条分界线---------------------------------------------------------------
接下来是重点,为列表添加一套自己的样式,以下是我的样式表:
简单的解析:根据代码中绿色文字分隔不同的步骤(字多不看的请忽略这一段)
第一步:为最外层容器设置样式,包括容器的位置、高度、边框。我这里是固定到窗口右侧,垂直居中;自动根据列表项的多少滚动显示隐藏内容;设置边框以及圆角
第二步:统一去除列表项前面的小圆点
第三步:为链接添加文字颜色,无背景色,上下边框(左右无),去除链接的下划线,让链接充满父元素宽度,并设置透明度;然后是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做实例化,是因为直接插入后我的代码变成了下面这样:
博客园默认添加了//
// ]]>的注释,将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还可以给列表增加更多神奇的功能。