在Heox中即使再长的代码,默认发布出来很长,也不会进行折叠。这怎么能忍?本文介绍如何在Hexo中实现类型代码折叠功能,让文章看起来更加清爽
先上效果
费话不多说,看看效果:
本博客目前采用的方案,即是这种。
前题&思路
本博客环境:hexo@5.4.0
,next@8.2.2
,以下所有代码,建立在这个基础之上。
由 jQuery 选择器选择代码模块.highlight
相关的DOM节点,给超过某个高度的代码模块添加展开收起的盒子,让盒子实现展开隐藏效果。
折叠逻辑
添加code-unfold.js
由于是在next
主题中添加js逻辑,所以我们把code-unfold.js
放置在了themes/next/source/js/code-unfold.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| var CODE_MAX_HEIGHT = 200; var containers = [];
$('body').on('click', '.js_unfold_code_btn', function () { $(this).closest('.js_highlight_container').addClass('on'); });
$('body').on('click', '.js_retract_code_btn', function () { var $container = $(this).closest('.js_highlight_container').removeClass('on'); var winTop = $(window).scrollTop(); var offsetTop = $container.offset().top; $(this).css('top', 0); if (winTop > offsetTop) { $('body, html').animate({ scrollTop: $container.offset().top - CODE_MAX_HEIGHT }, 600); } });
$(window).on('scroll', function () { var scrollTop = $(window).scrollTop(); var temp = []; for (let i = 0; i < containers.length; i++) { var item = containers[i]; var { $container, height, $hide, hasHorizontalScrollbar } = item; if ($container.closest('body').length === 0) { continue; } temp.push(item); if (!$container.hasClass('on')) { continue; } var offsetTop = $container.offset().top; var hideBtnHeight = $hide.outerHeight(); var maxTop = parseInt(height - (hasHorizontalScrollbar ? 17 : 0) - hideBtnHeight); let top = parseInt( Math.min( Math.max(scrollTop - offsetTop, 0), maxTop, ) ); var halfHeight = parseInt($(window).height() / 2 * Math.sin((top / maxTop) * 90 * (2 * Math.PI/360))); $hide.css('top', Math.min(top + halfHeight, maxTop)); } containers = temp; });
function addCodeWrap($node) { var $container = $node.wrap('<div class="js_highlight_container highlight-container"><div class="highlight-wrap"></div></div>').closest('.js_highlight_container');
var $btn = $(` <div class="highlight-footer"> <a class="js_unfold_code_btn show-btn" href="javascript:;">展开代码<i class="fa fa-angle-down" aria-hidden="true"></i></a> </div> <a class="js_retract_code_btn hide-btn" href="javascript:;"><i class="fa fa-angle-up" aria-hidden="true"></i>收起代码</a> `);
$container.append($btn); return $container; };
function codeUnfold () { $('.highlight').each(function () { if (this.__render__ === true) { return true; } this.__render__ = true; var $this = $(this); var height = $(this).outerHeight(); if (height > CODE_MAX_HEIGHT) { var $container = addCodeWrap($this, height); containers.push({ $container, height, $hide: $container.find('.js_retract_code_btn'), hasHorizontalScrollbar: this.scrollWidth > this.offsetWidth, }); } }); };
|
添加jquery
由于需要使用jquery
在next
主题文件中
方案一:
修改配置:
因为fancybox
会依赖jquery
,所以设置成true
方案二:在next
主题全局引用jquery
引用code-unfold.js
修改文件themes/next/layout/_scripts/index.njk
1 2
| {{- next_js('code-unfold.js') }}
|
下面找到文件themes/next/source/js/next-boot.js
:
1 2 3 4 5
| NexT.boot.refresh = function () { codeUnfold()
|
添加样式
创建highlight.styl
可以添加theme/next/source/css/_common/components/highlight.styl
文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| .highlight-container position: relative background-color: highlight-background &.on .highlight-footer display: none .hide-btn display: flex .highlight-wrap max-height: none .highlight-wrap overflow: hidden max-height: 200px .highlight-footer position absolute width: 100% left: 0 bottom: 0 height: 60px background-image: 'linear-gradient(-180deg, rgba(255,255,255,0) 0%, %s 65%)' % highlight-background; text-align: center .show-btn font-size: 12px color: #fff position: absolute left: 50% transform: translateX(-50%) bottom: 0 line-height: 2em text-decoration: none padding: 0 0.8em text-align: center border-radius: 4px 4px 0 &:hover text-decoration: none .hide-btn color: #fff font-size: 12px width: 22px position: absolute left: -21px top: 0 line-height: 1em text-decoration: none text-align: center display: none flex-direction: column background-color: highlight-background border-radius: 4px 0 0 4px padding: 0.1em 0 0.6em transition: top ease 0.35s .fa-angle-up, .fa-angle-down font-style: normal color: #fff .fa-angle-up:before content:"\f106" .fa-angle-down:before content:"\f107" margin-left: 0.5em .js_unfold_code_btn, .js_retract_code_btn background: rgba(0,0,0,0.5) border-bottom: none !important &:hover border-bottom-color: none !important
|
引用样式
找到文件themes/next/source/css/_common/components/index.styl
:
1 2 3 4 5
| @import 'post'; @import 'pages'; @import 'third-party';
@import 'highlight'
|
至此,我们就完成了hexo博客长代码折叠功能。