Wagtail 教程系列 记录了基于 Wagtail 搭建博客站点的整个过程,博客站点 所呈现的即是搭建过程的最新效果。

更多 Wagtail 内容:https://slowread.cn/wagtail-tutorials

自动生成文章右侧TOC导航

此部分属于通用内容,非 Wagtail 必需内容,是为了完善/优化基于 Wagtail 搭建的博客。

说明

  • 需要在文章页面中创建一对 DIV 标签,涵盖范围为需要自动生成TOC导航的文章内容部分,ID 为 JS 脚本中设定的名字 sowread_post_body。
  • JS 脚本自动查找第一个标题级别,只显示两级目录。

CSS


/* TOC 导航 */#TOCbar{text-align:left; position:fixed; width: auto; color:#2F7CFF;height: auto; top:4em; right:0; margin: 0.25em /*离页面顶部与右侧的距离*/
}
#TOCbarTab{float:left; width: 2.5em; border:1px solid #e5e5e5; border-right:none;text-align:center; background:#ffffff;
}
#TOCbarContents{float:left; overflow:auto; overflow-x:hidden; padding: 0.5em; color:#2F7CFF;width:18em; min-height:6em; max-height:50em;border:1px solid #e5e5e5; border-right:none; background:#ffffff;
}
#TOCbarContents dl{ margin:0; padding:0; }
#TOCbarContents dt{ margin-left: 0;}
#TOCbarContents dd{ padding-left: 1.5em; margin-bottom: 0;}
#TOCbarContents dd, dt { cursor: pointer; }
#TOCbarContents dd:hover, dt:hover { color:#ffffff;background:#2F7CFF;}/* TOC 导航 */

JavaScript


// 自动生成 TOC 导航var BlogDirectory = {/*获取元素位置,距浏览器左边界的距离(left)和距浏览器上边界的距离(top)*/getElementPosition:function (ele) {var topPosition = 0;var leftPosition = 0;while (ele){topPosition += ele.offsetTop;leftPosition += ele.offsetLeft;ele = ele.offsetParent;}return {top:topPosition, left:leftPosition};},/*获取滚动条当前位置*/getScrollBarPosition:function () {var scrollBarPosition = document.body.scrollTop || document.documentElement.scrollTop;return  scrollBarPosition;},/*移动滚动条,finalPos 为目的位置,internal 为移动速度*/moveScrollBar:function(finalpos, interval) {// 若不支持此方法,则退出if(!window.scrollTo) {return false;}// 窗体滚动时,禁用鼠标滚轮window.onmousewheel = function(){return false;};// 清除计时if (document.body.movement) {clearTimeout(document.body.movement);}var currentpos =BlogDirectory.getScrollBarPosition(); // 获取滚动条当前位置var dist = 0;if (currentpos == finalpos) { // 到达预定位置,则解禁鼠标滚轮,并退出window.onmousewheel = function(){return true;};return true;}if (currentpos < finalpos) { // 未到达,则计算下一步所要移动的距离dist = Math.ceil((finalpos - currentpos)/10);currentpos += dist;}if (currentpos > finalpos) {dist = Math.ceil((currentpos - finalpos)/10);currentpos -= dist;}var scrTop = BlogDirectory.getScrollBarPosition(); // 获取滚动条当前位置window.scrollTo(0, currentpos); // 移动窗口if(BlogDirectory.getScrollBarPosition() == scrTop) // 若已到底部,则解禁鼠标滚轮,并退出{window.onmousewheel = function(){return true;};return true;}// 进行下一步移动var repeat = "BlogDirectory.moveScrollBar(" + finalpos + "," + interval + ")"; document.body.movement = setTimeout(repeat, interval); },htmlDecode:function (text){var temp = document.createElement("div");temp.innerHTML = text;var output = temp.innerText || temp.textContent;temp = null;return output;},/*创建博客目录,id表示包含博文正文的 div 容器的 id,mt 和 st 分别表示主标题和次级标题的标签名称,interval 表示移动的速度*/createBlogDirectory:function (id, mt, st, interval){// 获取博文正文div容器var elem = document.getElementById(id);if(!elem) return false;// 获取div中所有元素结点var nodes = elem.getElementsByTagName("*");// 创建博客目录的div容器var divTOCbar = document.createElement('DIV');divTOCbar.className = 'TOCbar';divTOCbar.setAttribute('id', 'TOCbar');var divTOCbarTab = document.createElement('DIV');divTOCbarTab.setAttribute('id', 'TOCbarTab');divTOCbar.appendChild(divTOCbarTab);var h3 = document.createElement('h4');divTOCbarTab.appendChild(h3);var txt = document.createTextNode('<'); // 目录导航名字h3.appendChild(txt);var divTOCbarContents = document.createElement('DIV');divTOCbarContents.style.display = 'none';divTOCbarContents.setAttribute('id', 'TOCbarContents');divTOCbar.appendChild(divTOCbarContents);// 创建自定义列表var dlist = document.createElement("dl");divTOCbarContents.appendChild(dlist);var num = 0; // 统计找到的mt和st//   mt = mt.toUpperCase(); // 转化成大写//   st = st.toUpperCase(); // 转化成大写mt = "H1";st = "H2";var hhArray = ["H1","H2","H3","H4","H5","H6"];// 查找第一个 标题 级别,如果找到 自动设置下一级标题for(var x=0; x<nodes.length; x++){if ($.inArray(nodes[x].nodeName,hhArray) != -1){mt = hhArray[$.inArray(nodes[x].nodeName,hhArray)];if ($.inArray(nodes[x].nodeName,hhArray) <= 4){st = hhArray[$.inArray(nodes[x].nodeName,hhArray) + 1];}break;}}// 遍历所有元素结点for(var i=0; i<nodes.length; i++){if(nodes[i].nodeName == mt|| nodes[i].nodeName == st){// 获取标题文本var nodetext = nodes[i].innerHTML.replace(/<\/?[^>]+>/g,""); // innerHTML里面的内容可能有HTML标签,所以用正则表达式去除HTML的标签nodetext = nodetext.replace(/&nbsp;/ig, ""); // 替换掉所有的 &nbsp;nodetext = BlogDirectory.htmlDecode(nodetext);// 插入锚nodes[i].setAttribute("id", "blogTitle" + num);var item;switch(nodes[i].nodeName){case mt:    // 若为主标题item = document.createElement("dt");break;case st:    // 若为子标题item = document.createElement("dd");break;}// 创建锚链接var itemtext = document.createTextNode(nodetext);item.appendChild(itemtext);item.setAttribute("name", num);item.onclick = function(){        // 添加鼠标点击触发函数var pos = BlogDirectory.getElementPosition(document.getElementById("blogTitle" + this.getAttribute("name")));if(!BlogDirectory.moveScrollBar(pos.top, interval)) return false;};// 将自定义表项加入自定义列表中dlist.appendChild(item);num++;}}if(num == 0) return false;/* 鼠标进入时的事件处理 */divTOCbarTab.onmouseenter = function(){divTOCbarContents.style.display = 'block';};/* 鼠标离开时的事件处理 */divTOCbar.onmouseleave = function() {divTOCbarContents.style.display = 'none';};document.body.appendChild(divTOCbar);}};window.onload=function(){/* 页面加载完成之后生成博客目录 */
// h2,h3 非必须指定,程序内部自动查找第一个标题级别     2018-12-21BlogDirectory.createBlogDirectory("sowread_post_body","h2","h3",20);
};// 自动生成 TOC 导航

Wagtail 教程 4:自动生成文章右侧TOC导航相关推荐

  1. 自动生成文章的html,文章自动更新工具|自动生成文件|自动伪原创|文章自动插入关键词工具...

    概念网络发布一款自动更新文章的工具, 该套工具可用概念的文章站程序, 概念的发布站程序, 概念的企业站程序, 只要在服务器一直开着这个工具, 工具会更具配置文件的配置, 每天定时的更新网站的文章, 文 ...

  2. python心得体会200字_50行代码让python自动生成文章

    不知道从小到大,我们被迫写了多少心得体会,多少人生感想,如果真情实地的去感受写作然后成长当然很好,但是更多的都是形式主义的需求,并没有人去看里面的内容,白白浪费我们多少大好时光,有时候我们ctrl,C ...

  3. doc自动生成html,java web应用中自动生成文章html页面的实现.doc

    java web应用中自动生成文章html页面的实现 java web应用中自动生成文章html页面的实现 2009-11-09 00:24:15 标签:web开发,页面转换 [推送到技术圈] 版权声 ...

  4. python自动化写作_50行代码让python自动生成文章

    不知道从小到大,我们被迫写了多少心得体会,多少人生感想,如果真情实地的去感受写作然后成长当然很好,但是更多的都是形式主义的需求,并没有人去看里面的内容,白白浪费我们多少大好时光,有时候我们ctrl,C ...

  5. Python 自动化教程(5) : 自动生成Word文件

    系列教程: Python 自动化教程(1) 概述,第一篇 Excel自动化 Python 自动化教程(2) : Excel自动化:使用pandas库 Python 自动化教程(3) : 自动生成PPT ...

  6. 输入关键词自动生成文章-免费自动输入关键词自动生成文章器

    输入关键词自动生成文章,什么是输入关键词自动生成文章?例:你输入什么关键词 '装修'免费工具会自动生成一篇跟装修相关的文章,该免费工具还支持:自动关键词文章生成+文章自动采集+伪原创+自动发布+自动推 ...

  7. Django 快速搭建博客 第十一节(文章阅读量统计,自动生成文章摘要)

    这一节主要做一些修补工作,一个是:文章阅读量的统计,另一个是自动生成文章摘要内容 1 . 文章阅读量的统计: 1 文章阅读量的统计,我们需要在model下的Post类中新加入一个views 字段用来统 ...

  8. 根据文章中H标签自动生成文章目录

    以前看到csdn上的目录结构就想把它移植到博客里,今天抽了个空从csdn上拔下了代码. js代码,复制放入到single.php页面中 <script type="text/javas ...

  9. Python 自动化教程(4) : 自动生成PPT文件 Part 2 (干货)

    系列教程: Python 自动化教程(1) 概述,第一篇 Excel自动化 Python 自动化教程(2) : Excel自动化:使用pandas库 Python 自动化教程(3) : 自动生成PPT ...

  10. 写文章很难,ai自动生成文章为你来排忧

    常常听到有人说写文章难,一篇文章不知如何开头,一篇文章写了又删,删了又写,一篇文章要写几个小时等等问题,对于那些不喜欢写作的人来说,写文章确实挺难的.但是由于工作中的原因有时候又不得不写,写又写不出内 ...

最新文章

  1. Error - section 'InterruptVectorLow' can not fit the absolute section. Section 'InterruptVectorLow'
  2. 基于梅尔频谱的音频信号分类识别(Pytorch)
  3. 牛客网_PAT乙级1004_福尔摩斯的约会 (20)
  4. python生成多个列表_python生成多个只含0,1元素的随机数组或列表(代码)
  5. 带你自学Python系列(九):一文读懂Python中字典应用原理!
  6. Hough transform(霍夫变换)
  7. android系统性能优化(61)---如何降低Android应用程序的耗电量
  8. ros开发增加clion常用模板及初始化配置(五)
  9. nagios扩展开发之check_ping
  10. No module named ‘lightgbm‘
  11. 3389、135、137、138、139、445等端口解释和关闭方法
  12. [iOS]寻找superView
  13. 中安未来护照阅读器助力电子客票的推广和落实让你的出行说走就走
  14. 计算机视觉基础知识点(根据cs231n以及博客内容整理)
  15. 王者荣耀服务器维护七月,《王者荣耀》7.28不停服维护更新攻略教程 7月28日更新公告...
  16. CSS图片保持原比例
  17. Vue.js如何获得兄弟元素,子元素,父元素(DOM操作)
  18. 最全-python教程示例大全 同步学习
  19. Prometheus监控模板
  20. Graphviz - 生成smc 的.sm文件对应的工作流程图

热门文章

  1. php微信测试号配置代码,微信测试号实现微信分享等功能【转载】
  2. 最小割集Stoer-Wagner算法
  3. TC27x启动过程(2)-TC277
  4. srs信道估计_SRS 上行信道质量测量
  5. Scratch(五):Scratch小游戏之超级玛丽
  6. 增强 扫描王 源码_camscanner(扫描全能王)功能解析与复现 - 页面增强
  7. 2003- cant connect to MYSQL server on localhost(10061)
  8. python参数类型为uint8_Python 改变数组类型为uint8的实现
  9. [HDU - 3709] Balanced Number (数位dp)
  10. 除了努力挣钱,青春也不能错过的十件事