Hexo添加在线运行html/css/js代码插件

先看效果

在线运行代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="time" style="font-size: 26px;text-align: center"></div>
<script>
var i = 0;
function myDate() {
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var hours = now.getHours();
var minutes = now.getMinutes();
var seconds = now.getSeconds();

document.getElementById("time").innerHTML =
year + "年" +
month + "月" +
day + "日<br/>" +
hours + ":" +
minutes + ":" +
'<font color="#f54949">'+seconds+'</font>';
}

setInterval(myDate, 1000);
</script>

使用的插件

地址:https://github.com/denghao123/jquery.runCode.js.git

引入到hexo:

  1. 将代码clone到本地后,在~/themes/next/source/js/src文件夹新建文件夹runcode
  2. jquery.min.js jquery.runCode.css jquery.runCode.js 三个文件放到runcode文件下

分析

需求:点击按钮,执行代码块内的html/css/js代码,并且要动态配置改代码块是否需要添加执行代码功能

第一想到是Hexo自带的代码复制功能(参阅文章Hexo折腾-开启代码复制功能),和此需求非常相似,只不过代码复制功能是全局配置开启,所有代码块都有该功能。

hexo的复制代码的部分源码:

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
//查找源码,看到每个代码块元素都添加了一个复制按钮
<button class="copy-btn">复制</button>

//通过按钮的copy-btn查找js代码,如下
$('.highlight').each(function (i, e) {
var $wrap = $('<div>').addClass('highlight-wrap');
$(e).after($wrap);
$wrap.append($('<button>').addClass('copy-btn').append('复制').on('click', function (e) {
var code = $(this).parent().find('.code').find('.line').map(function (i, e) {
return $(e).text();
}).toArray().join('\n');
var ta = document.createElement('textarea');
var range = document.createRange(); //For Chrome
var sel = window.getSelection(); //For Chrome
var yPosition = window.pageYOffset || document.documentElement.scrollTop;
ta.style.top = yPosition + 'px'; //Prevent page scroll
ta.style.position = 'absolute';
ta.style.opacity = '0';
ta.value = code;
ta.textContent = code; //For FireFox
ta.contentEditable = true;
ta.readOnly = false;
document.body.appendChild(ta);
range.selectNode(ta);
sel.removeAllRanges();
sel.addRange(range);
ta.setSelectionRange(0, code.length);
var result = document.execCommand('copy');

if (result) $(this).text('复制成功');
else $(this).text('复制失败');

ta.blur(); //For iOS
$(this).blur();
})).on('mouseleave', function (e) {
var $b = $(this).find('.copy-btn');
setTimeout(function () {
$b.text('复制');
}, 300);
}).append(e);
})

添加运行代码的按钮

由于本人博客用的是自定义代码块,原生代码块需自行研究。(自定义代码块参阅文章Hexo折腾-代码块上显示当前语言名称)

在自定义代码块时,写了一个JS用来处理每个代码块上的title,我们可以用这个JS来动态添加运行代码的按钮。

定义:代码块上的标签有且大于等于2个都时候(不包括开始的代码语言标签),第二个标签为控制是否动态添加运行代码按钮的标识,这个标识为runcode
例:diff 文件路径:~/htemes/next/scripts/codeblock.js runcode

codeblock.js代码修改如下

  1. 判断当前标签数量是否为2个
  2. 取第二个标签,判断标签是否runcode
  3. 生成一个随机ID
  4. 给你运行代码按钮添加data-*数据,值为刚才生成的ID
  5. 给代码块的第一个父元素figure 添加ID,值为生成的ID
  6. 将运行代码按钮拼接放在代码块的最外层(为了不影响代码块的原来样式🤪,[其实是懒,你可以用定位放在任意位置])
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
var attributes = [
'autocomplete="off"',
'autocorrect="off"',
'autocapitalize="off"',
'spellcheck="false"',
'contenteditable="true"'
]

var attributesStr = attributes.join(' ')

+ /**
+ * 生成 [n,m]的随机数
+ * @param minNum
+ * @param maxNum
+ * @returns {number}
+ */
+ function randomNum(minNum, maxNum) {
+ switch (arguments.length) {
+ case 1:
+ return parseInt(Math.random() * minNum + 1, 10);
+ break;
+ case 2:
+ return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
+ break;
+ default:
+ return 0;
+ break;
+ }
+ }

// hexo 渲染引擎 https://hexo.io/zh-cn/api/renderer
hexo.extend.filter.register('after_post_render', function (data) {

while (/<figure class="highlight ([a-zA-Z]+)">.*?<\/figure>/.test(data.content)) {
data.content = data.content.replace(/<figure class="highlight ([a-zA-Z]+)">.*?<\/figure>/, function () {

var language = RegExp.$1
var notSupport = "plain"
if (language == notSupport) {
//不知高亮的语言
language = ""
}

var lastMatch = RegExp.lastMatch
+ //运行代码按钮
+ var runcodeBtn = ""
lastMatch = lastMatch.replace(/<figure class="highlight /, '<figure class="iseeu highlight /')

var title = ""
// 处理 figcaption 标签 eg:<figcaption><span>文件路径:~/blog/themes/next/scripts/codeblock.js</span></figcaption>
var figFirst= lastMatch.indexOf("<figcaption")
if (figFirst > 0) {
//有 figcaption 标签
var figLast= lastMatch.indexOf("</figcaption")
//</figcaption> 回标签长度
var len = 13
figLast+= len
//截取 figcaption 标签内容
var figStr= lastMatch.substring(figFirst,figLast)
//删除 figcaption 标签
lastMatch = lastMatch.replace(figStr,"")

//获取 [title] [url] [link-text]
var spanStr = figStr.replace("<figcaption><span>","").replace("</span></figcaption>","")

//根据空格分割
var resultContent = spanStr.split(" ")
if (resultContent.length > 0) {
//取第一个title
title = " " + resultContent[0]
}

+ if (resultContent.length > 1) {
+ if (resultContent[1] =="runcode") {
+ //添加ID
+ var id = "runcode"+randomNum(1,1000);
+ //添加运行代码按钮
+ runcodeBtn = '<button class="run-code" data-figure-id= '+id+'>运行代码</button>';
+ lastMatch = lastMatch.replace('<figure class="iseeu highlight /', '<figure id='+id+' class="iseeu highlight /')
+
+ }
+ }
}

+ return runcodeBtn + '<div class="highlight-wrap"' + attributesStr + 'data-rel="' + language + title + '">' + lastMatch + '</div>'
})
}
return data
})

在任意代码块添加标签如java 测试按钮 runcode
然后执行hexo cl && hexo g && hexo s,你将会在该代码块上看见一个HTML的运行代码按钮。
然鹅这个按钮太长丑了,我们给它美化美化

  1. 找到文件:~/htemes/next/layout/_layout.swig,将刚刚导入的CSS文件jquery.runCode.css,引入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <head>
    {{ partial('_partials/head/head.swig', {}, {cache: theme.cache.enable}) }}
    {% include '_partials/head/head-unique.swig' %}
    <title>{% block title %}{% endblock %}</title>
    {% include '_third-party/analytics/index.swig' %}
    {{ partial('_scripts/noscript.swig', {}, {cache: theme.cache.enable}) }}

    + <link rel="stylesheet" href="/js/src/runcode/jquery.runCode.css">
    + <script src="/js/src/runcode/jquery.min.js"></script>
    </head>
  2. 然后在jquery.runCode.css文件中新增run-code,当前你也可以在~/htemes/next/source/css/_custom文件夹下修改样式(还是懒的🤪)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .run-code{
    background-color: #f54949;
    color: #ffffff;
    font-size: 14px;
    border-radius: 4px;
    }
    .run-code:focus{
    outline: none !important;
    outline-color: #00000000;
    }
  3. 保存执行hexo cl && hexo g && hexo s即可

点击按钮运行代码

  1. 找到文件:~/htemes/next/layout/_layout.swig,在<main>标签的内部最后添加<textarea>代码容器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        <main id="main" class="main">
    <div class="main-inner">
    <div class="content-wrap">
    {% if theme.scheme === 'Pisces' || theme.scheme === 'Gemini' %}
    {% include '_partials/header/sub-menu.swig' %}
    {% endif %}
    <div id="content" class="content">
    {% block content %}{% endblock %}
    </div>
    {% include '_partials/comments.swig' %}
    </div>
    {% if theme.sidebar.display !== 'remove' %}
    {% block sidebar %}{% endblock %}
    {% endif %}
    </div>
    + <textarea hidden="true" class="run-code-text"></textarea>
    </main>
  2. <body>标签的内部最后添加如下如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!-- 代码运行 -->
    <script src="/js/src/runcode/jquery.runCode.js"></script>
    <script>
    $(".run-code").on('click', function() {
    //获取ID
    var id = this.getAttribute("data-figure-id");
    console.log(id);
    //获取代码
    var code = $("#"+id).find('.code').find('.line').map(function (i, e) {
    return $(e).text();
    }).toArray().join('\n');

    var textareaCode = $(".run-code-text");
    textareaCode.text(code);
    textareaCode.runCode();
    })

    </script>
  3. 保存执行hexo cl && hexo g && hexo s即可

使用

  1. 开启在线运行代码

    1
    2
    3
    ```html 测试代码 runcode
    <div> 测试 runcode </div>
    ```
  2. 关闭在线运行代码(默认)

    1
    2
    3
    ```html 测试代码
    <div> 测试 runcode </div>
    ```

最后:可修改jquery.runCode.css文件,自定义代码运行弹窗的样式


Hexo系列文章:https://mecono.cn/categories/Hexo/

--- 青山不改 绿水长流,日后江湖相见,自当杯酒言欢,咱们就此别过。---

本文标题:Hexo添加在线运行html/css/js代码插件

文章作者:mecono

发布时间:2019年08月09日 - 09:08

最后更新:2019年12月19日 - 09:12

原始链接:https://mecono.cn/2425951001.html

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-ND 4.0许可协议。转载请注明出处!