代码大致分为三段:

第一段是html

1
2
3
4
5
6
7
<div id='textblock'>
<div>
<h3 id='tb-content'>「小楼一夜听春雨,深巷明朝卖杏花。」</h3>
<p id='tb-from'>《临安春雨初霁》陆游</p>
<button id='tb-refresh-btn' onclick='getSentence();'>换一换</button>
</div>
</div>

第二段是javascript

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
<script>

var sentenceType={
'a':'动画',
'b':'漫画',
'c':'游戏',
'd':'文学',
'e':'原创',
'f':'网络',
'g':'其他',
'h':'影视',
'i':'诗词',
'j':'网易云',
'k':'哲学',
'l':'抖机灵'
}

function getSentence(){loadDoc();}

function loadDoc(){
var oldx = document.getElementById('textblock').innerHTML;
document.getElementById('tb-content').innerHTML='加载中...'; //tb-content是第一行的句子内容。
document.getElementById('tb-from').innerHTML=''; //tb-from是第二行的出处,包括作者和作品。

//XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。
var xhttp = new XMLHttpRequest();
//readyState == 4描述一种"已加载"状态;此时,响应已经被完全接收。status == 200表示成功收到。
xhttp.onreadystatechange = function(){
if(this.readyState == 4 &&this.status == 200){
myFunction(this);
}
else{
window.setTimeout(function(){ //等三秒钟,还没有成功就返回上一次。
var text = document.getElementById('tb-content').innerText;//innerText 属性设置或返回指定节点及其所有子节点的文本内容。
if(text=='加载中...')
document.getElementById('textblock').innerHTML=oldx;
},3000);
}
}
xhttp.open('GET','https://fanyiming.life/oneword.json',true); //存放json文件的地址。
xhttp.send();
}


function myFunction(xml){
var xmlDoc = xml.response;
var json = JSON.parse(xmlDoc); //JSON.parse函数将json文件转换成javascript数组格式。

var jslength=0; //计算数组长度,即一共有几条句子,jslength返回长度-1。
for(var x in json){
jslength++;
}
var random_no = Math.floor(Math.random()*100000%jslength); //随机取
var json1 = json[random_no];
var hito = json1.hitokoto;
var type_= json1.type;
var typeDiscription = sentenceType[type_];
var from = json1.from;
var auth = json1.from_who;

if(auth==from)auth=null;

var ls=['a','b','c','d','h','i','k'];
if(ls.indexOf(type_)>-1) {if(from.indexOf('《')<0) from = '《'+from+'》';}

var from_info='';
if(auth==null) from_info = from;
else{
if(from.indexOf('《')<0){
from_info = from + '&nbsp;·&nbsp;' + auth;
}
else from_info = from + auth;
}
document.getElementById('tb-content').innerHTML = hito;
document.getElementById('tb-from').innerHTML = from_info;
}
loadDoc();
</script>

第三段是css

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
<style>
#textblock{
margin:0px 0px 0px 0px;
border:0 0 0 0;
text-align: center;
padding: 0px 0px 0px 0px;
height:auto;
}
#textblock div{
display: inline-block;
}
#textblock div h3{
margin:18px 0 0 0;
text-align:center;
font-size:20px;
font-weight: normal;
}
#textblock div p{
margin:5px 0 5px 0;
width:100%;
text-align:right;
font-size:16px;
}
#tb-refresh-btn{
width:84px;
height: 42px;
float: right;
margin: 0px 0 0 0 ;
border: 0px;
padding: 0 0px 0 0px;
background-color: rgb(11, 153, 122);
color: #fff;
font-size: 16px;
font-weight: bold;
box-shadow: 0px 0px 4px rgba(127,127,198,0.5);
cursor: pointer;
}
#tb-refresh-btn:hover {background-color: rgb(66, 190, 150);}
#tb-refresh-btn:active {background-color: rgb(66, 190, 150);}
</style>

用的时候,直接一起复制到网页里就可以了。我想放在说说页面,所以插入在了~\node_modules\hexo-bb\templates\bb.ejs文件里面。(不小心把说说头部显示的文字功能弄丢了,目前也用不到,以后再说)

添加句子的时候,可以现在xlsx里面编辑好,然后在Convert Excel to JSON Array - Table Convert Online中转换成JSON文件,更新一下博客根目录下的oneword.json就可以了。

有一个特别需要注意的点,hexo-NexT竟然会渲染json文件,导致json文件的末尾多了一串javascript的代码,然后JSON.parse这个函数对于参数特别严格,括号里必须是严格的json字符串格式。于是渲染之后就一直错误。这个问题花了我四个小时左右的时间。草。F12是个好东西。还有要学会用console.log()进行调试,也很有用。

在根目录下的_config.yml文件中,把json文件添加到skip_render下,解决这个问题。

image-20220808074051941


感谢一言网为爱发电的作者们(关于我们 - 一言 (hitokoto.cn)


在以下两个网站浅浅了解了一下JSON和XML。

JSON 教程 | 菜鸟教程 (runoob.com)

XML 教程 | 菜鸟教程 (runoob.com)