最近使用Butterfly主题的博友都在对博客随机友链功能做优化。

随机友链优化案例

张洪Heo 使用的是js读取本地json文件,通过编辑json文件即可实现增删改友链。

部分代码如下,详细可以看作者源码

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
addFriendLinksInFooter: function() {
fetch("/zhheo/friendlink.json").then((e=>e.json())).then((e=>{
var t = []
, o = -1;
for (const n of e) {
const e = n.link_list;
for (let n = 0; n < Math.min(e.length, 1); n++) {
let n = Math.floor(Math.random() * e.length);
for (; n === o && e.length > 1; )
n = Math.floor(Math.random() * e.length);
o = n,
t.push({
name: e[n].name,
link: e[n].link
}),
e.splice(n, 1)
}
}
t.pop();
var n = "";
for (let e = 0; e < t.length; ++e) {
var a = t[e];
n += `<a class='footer-item' href='${a.link}' target="_blank" rel="noopener nofollow">${a.name}</a>`
}
n += "<a class='footer-item' href='/link/'>更多</a>",
document.getElementById("friend-links-in-footer").innerHTML = n
}
))
}

jayhrn 使用的是Hexo过滤器,读取的博客友链页面的所有链接。

部分代码如下,详细可以看作者原文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
hexo.extend.filter.register('after_render:html', function (data) {
const flinks = []
hexo.locals.get('data').link.map(function (list) {
list.link_list.map(function (flink) {
flinks.push(flink)
})
})
data += `<script>
function getRandomFlink(num) {
let AllFinlks=${JSON.stringify(flinks)}
let randomLinks = [];
while (randomLinks.length < num && AllFinlks.length > 0) {
let index = Math.floor(Math.random() * AllFinlks.length);
randomLinks.push(AllFinlks.splice(index, 1)[0]);
}
return randomLinks;
}
</script>`
return data
})

测试优化后的效果

因为不想维护过多的json文件,所以使用jayhrn的逻辑做了测试,效果不错,速度快并且稳定,不依赖其他json文件。

随机友链在我的博客里面有三个功能:

  1. 首页右上角点击 提示跳转 指定友链地址;
  2. 全站页脚左下角点击 随机友链 使用新窗口打开友链地址;
  3. 全站页脚随机展示 两个友链 点击后新窗口打开友链地址;

基于jayhrn的逻辑首次修改

更新themes/butterfly/scripts/helpers/random.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
/**
* 随机友链
*/
hexo.extend.filter.register('after_render:html', function (data) {
const flinks = []
hexo.locals.get('data').link.map(function (list) {
list.link_list.map(function (flink) {
flinks.push(flink)
})
})
data += `<script>
function toRandomFlink() {
let flinksTo=${JSON.stringify(flinks)}
window.open(flinksTo[Math.floor(Math.random() * flinksTo.length)].link)
}
function RandomFlink() {
let flinksRan=${JSON.stringify(flinks)}
let e = flinksRan[Math.floor(Math.random() * flinksRan.length)]
return e
}
function getRandomFlink(num) {
let flinksGet=${JSON.stringify(flinks)}
let randomLinks = [];
while (randomLinks.length < num && flinksGet.length > 0) {
let index = Math.floor(Math.random() * flinksGet.length);
randomLinks.push(flinksGet.splice(index, 1)[0]);
}
return randomLinks;
}
</script>`
return data
})

修改引用js的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 添加随机友链提示跳转
function travelling() {
let fetchUrl = RandomFlink()
if(fetchUrl) {
var name = fetchUrl.name;
var link = fetchUrl.link;
let msg = "点击前往按钮进入随机一个友链,不保证跳转网站的安全性和可用性。本次随机到的是本站友链:「" + name + "」";
document.styleSheets[0].addRule(':root', '--LHL-snackbar-time:' + 8000 + 'ms!important');
Snackbar.show({
text: msg,
duration: 8000,
pos: 'top-center',
actionText: '前往',
onActionClick: function (element) {
$(element).css('opacity', 0);
window.open(link, '_blank');
}
});
}
}
1
2
3
4
5
6
7
8
9
10
11
// 添加底部友链
addFriendLinksInFooter: function () {
let randomFriendLinks=getRandomFlink(2)
let htmlText = '';
for (let i = 0; i < randomFriendLinks.length; ++i) {
let item = randomFriendLinks[i]
htmlText += `<a class='footer-item' href='${item.link}' target="_blank" rel="noopener nofollow">${item.name}</a>`;
}
htmlText += `<a class='footer-item' href='/link'>更多</a>`
document.getElementById("friend-links-in-footer").innerHTML = htmlText;
},
1
2
// 添加随机友链直接跳转
<a class="footer-item" onclick="toRandomFlink()" data-pjax-state="">随机友链</a>

测试结果还是比较满意,但是有个小问题,就是前端页面会生成三组相同的数组,友链越多占用的前端响应时间越多,所以最大化前端性能,第二次修改代码。

二次修改

修改为使前端将友链生成一组数组,然后随机友链的三个功能使用时分别浅拷贝即可。

更新themes/butterfly/scripts/helpers/random.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 随机友链
*/
hexo.extend.filter.register('after_render:html', function (data) {
const flinks = []
hexo.locals.get('data').link.map(function (list) {
list.link_list.map(function (flink) {
flinks.push(flink)
})
})
data += `<script>let flinksAll=${JSON.stringify(flinks)};</script>`
return data
})

修改引用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
// 添加随机友链提示跳转
function travelling() {
let flinksRandom = Array.from(flinksAll);
let fetchUrl = flinksRandom[Math.floor(Math.random() * flinksRandom.length)]
if(fetchUrl) {
var name = fetchUrl.name;
var link = fetchUrl.link;
let msg = "点击前往按钮进入随机一个友链,不保证跳转网站的安全性和可用性。本次随机到的是本站友链:「" + name + "」";
document.styleSheets[0].addRule(':root', '--LHL-snackbar-time:' + 8000 + 'ms!important');
Snackbar.show({
text: msg,
duration: 8000,
pos: 'top-center',
actionText: '前往',
onActionClick: function (element) {
$(element).css('opacity', 0);
window.open(link, '_blank');
}
});
}
},
// 添加底部友链直达
function toRandomFlink() {
let flinksTo = Array.from(flinksAll);
window.open(flinksTo[Math.floor(Math.random() * flinksTo.length)].link)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 添加底部友链
addFriendLinksInFooter: function () {
let flinksFooter = Array.from(flinksAll);
let randomFriendLinks = [];
while (randomFriendLinks.length < 2 && flinksFooter.length > 0) {
let index = Math.floor(Math.random() * flinksFooter.length);
randomFriendLinks.push(flinksFooter.splice(index, 1)[0]);
}
let htmlText = '';
for (let i = 0; i < randomFriendLinks.length; ++i) {
let item = randomFriendLinks[i]
htmlText += `<a class='footer-item' href='${item.link}' target="_blank" rel="noopener nofollow">${item.name}</a>`;
}
htmlText += `<a class='footer-item' href='/link'>更多</a>`
document.getElementById("friend-links-in-footer").innerHTML = htmlText;
}

至此修改完成,效果也不错,不过js的语法可能比较基础,希望可以抛砖引玉,有更高级写法的大佬欢迎讨论。