Hexo Theme Icarus 的代码折叠功能很喜欢,奈何 NexT 主题不支持相应的样式,也不打算支持,推荐的是使用 NOTE 块的实现方式,这很不优雅。
今天我发现在 NexT 主题中使用下面的格式时,代码块也会生成一个标题栏。
file or summary1 2 3
| ```js file or summary /* some code */ ```
|
那实现起来就很简单了,只需要掏出 F12 ,在 file or summary
前面插入一个按钮,然后为按钮添加功能。
不会写 JS 没有关系,只需要咨询一下 ChatGPT 。
配置主题加载自定义内容
在主题配置文件 _config.yaml
中,找到 custom_file_path
,取消对应的注释,允许加载自定义内容
themes/next/_config.yaml1 2 3
| custom_file_path: style: source/_data/styles.styl bodyEnd: source/_data/body-end.njk
|
然后在 Hexo 主目录下,创建对文件文件。
添加代码
在 body-end.njk
文件中,添加 JS 代码
source/_data/body-end.njk1 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
| <script> document.addEventListener("DOMContentLoaded", function() { const spans = document.querySelectorAll("figcaption > span"); spans.forEach(function(span) { const iElement = document.createElement("i"); iElement.className = "fas fa-angle-down"; iElement.innerHTML = " "; iElement.style.userSelect = "none"; span.parentNode.insertBefore(iElement, span); const tableContainer = span.parentElement.nextElementSibling; iElement.addEventListener("click", function() { tableContainer.classList.toggle("code-hidden"); if (iElement.classList.contains("fa-angle-down")) { iElement.classList.remove("fa-angle-down"); iElement.classList.add("fa-angle-right"); } else { iElement.classList.remove("fa-angle-right"); iElement.classList.add("fa-angle-down"); } }); }); }); </script>
|
在 styles.styl
填写对应的样式代码
source/_data/styles.styl1 2 3 4
| .code-hidden { display: none; }
|
加入后,运行本地预览 hexo g && hexo s
,效果非常完美。
现在的问题是,如果代码块不写 file or summary
内容的话,是没有这个 <figcaption>
标题栏的。
手动添加代码块标题栏
一两行的代码也没有必要进行折叠,所以添加一个检测,为大于三行且没有标题栏的代码块手动添加一个,最终 source/_data/body-end.njk
的代码如下
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
| <script> document.addEventListener("DOMContentLoaded", function() { const tableContainers = document.querySelectorAll(".table-container");
tableContainers.forEach(function(tableContainer) { const spanCount = tableContainer.querySelectorAll("tbody > tr > td.code > pre > span").length;
if (spanCount >= 3) { const prevElement = tableContainer.previousElementSibling; let figcaption; let iElement; if (!prevElement || prevElement.tagName.toLowerCase() !== "figcaption") { figcaption = document.createElement("figcaption");
tableContainer.parentNode.insertBefore(figcaption, tableContainer); } else { figcaption = prevElement; }
iElement = document.createElement("i"); iElement.className = "fas fa-angle-down"; iElement.innerHTML = " "; figcaption.insertBefore(iElement, figcaption.firstChild);
iElement.addEventListener("click", function() { tableContainer.classList.toggle("code-hidden");
if (iElement.classList.contains("fa-angle-down")) { iElement.classList.remove("fa-angle-down"); iElement.classList.add("fa-angle-right"); } else { iElement.classList.remove("fa-angle-right"); iElement.classList.add("fa-angle-down"); } }); } }); }); </script>
|
然后预览一下,看一下效果,没有问题的话就可以推送到服务器了。
测试