思路
- 首先我想到的是在本地用数组存储数据,然后设置定时器来随机读取数据并更新到页面,但是这种方式的弊端就是每次更新数据都要重新部署博客。
- 受之前使用
iframe
处理跨域的启发,我想到可以改用iframe
嵌入一个页面,在此页面中使用window.parent.postMessage('data', '*')
来向父页面推送数据,这样我们每次只需要更新此页面的文件即可,再把此页面挂到cos 桶或其他对象存储
上即可方便且高效复刻原有的随机图片与一言功能。 - 话不多说直接上代码
代码
嵌入页面
代码语言:javascript复制<!DOCTYPE html>
<html>
<head lang="zh-cn">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>博客 API</title>
</head>
<body>
<h1>Welcome</h1>
<script>
window.onload = () => {
const AVATARS = [
'/images/avatar.jpg',
'/images/xixi.png',
'/images/jienigui.jpg',
'/images/yunnan.jpg',
'/images/baoerjie.jpg',
'/images/ruikeandmodi.jpg',
'/images/biugle.png'
];
window.parent.postMessage({ type: 'avatar', value: AVATARS[new Date().getDay()] }, '*');
const WORDS = [
'人闲桂花落,夜静春山空。',
'不如意事常八九,可与言者无二三。',
'人间有味是清欢',
'君不见高堂明镜悲白发,朝如青丝暮成雪。',
'南朝四百八十寺,多少楼台烟雨中。',
'玲珑骰子安红豆,入骨相思知不知。',
'枯藤老树昏鸦,小桥流水人家,古道西风瘦马。夕阳西下,断肠人在天涯。',
'苟利国家生死以,岂因祸福避趋之。',
'人生自古谁无死,留取丹心照汗青。',
'我自横刀向天笑,去留肝胆两昆仑。',
...
];
window.parent.postMessage(
{ type: 'word', value: escape(WORDS[Math.floor(Math.random() * WORDS.length)]) }, // 中文使用 escape 编码防止乱码
'*'
);
setInterval(() => {
window.parent.postMessage(
{ type: 'word', value: escape(WORDS[Math.floor(Math.random() * WORDS.length)]) },
'*'
);
}, 10000);
window.parent.postMessage(
{ type: 'image', value: `/img/cdn/dev/avatar/${Math.floor(Math.random() * 50) 1}.png` },
'*'
);
setInterval(() => {
window.parent.postMessage(
{ type: 'image', value: `/img/cdn/dev/avatar/${Math.floor(Math.random() * 50) 1}.png` },
'*'
);
}, 30000);
};
</script>
</body>
</html>
父页面监听处理
代码语言:javascript复制window.addEventListener('message', (e) => {
const value = unescape(e.data.value);
switch (e.data.type) {
case 'word':
// do something
break;
case 'image':
// do something
break;
case 'avatar':
// do something
break;
}
});