其实刚开始部署 Memos 的时候,就看到 “大大的小蜗牛” 博主实现了,但是当时试了一下,没弄好,也懒得整了。今天正好有点空,就去研究了下,因为博主基本上是小白,“大大的小蜗牛”的教程我始终没有魔改成功,百度搜索了一番,发现“木木木木木”博主的首页也有滚动展示,发现也是 Memos 后端,直接就把博主的 JS 抄过来了,CSS 样式还是用的“大大的小蜗牛”博主的,再根据自己的主题稍微改一下。
创建 JS 文件
document.addEventListener("DOMContentLoaded", () => {
var bbDom = document.querySelector('#memos-say');
if (!bbDom) return;
var currentIndex = 0;
var timer = null;
var itemCount = 0;
function memoTalks() {
var bbUrl = "https://say.kaiqi.wang/api/v1/memos?creatorId=CatchWang&rowStatus=NORMAL&limit=10";
fetch(bbUrl).then(res => res.json()).then(resdata => {
var result = '', data = resdata.memos || [];
itemCount = data.length;
for (var i = 0; i < data.length; i++) {
var rawTime = data[i].createTime;
var bbTime = new Date(rawTime).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
var bbCont = data[i].content;
var newbbCont = bbCont
.replace(/```([\s\S]*?)```[\s]*/g, " <code>$1</code> ")
.replace(/`([\s\S ]*?)`[\s]*/g, " <code>$1</code> ")
.replace(/\!\[[\s\S]*?\]\([\s\S]*?\)/g, "🌅")
.replace(/\[[\s\S]*?\]\([\s\S]*?\)/g, "🔗")
.replace(
/\bhttps?:\/\/(?!\S+(?:jpe?g|png|bmp|gif|webp|jfif|gif))\S+/g,
"🔗"
);
// 附件图片转图标
if (data[i].attachments && data[i].attachments.length) {
var imgCount = data[i].attachments.filter(function (a) {
return a.type && a.type.indexOf('image/') === 0;
}).length;
if (imgCount > 0) {
newbbCont += ' ' + '🌅'.repeat(imgCount);
}
}
result += `<li class="item"><span class="datetime" datetime="${rawTime}">${bbTime}</span> <a href="/say/" target="_blank">${newbbCont}</a></li>`;
}
var bbBefore = `<span class="index-talk-icon"><svg viewBox="0 0 1024 1024" width="21" height="21"><path d="M184.32 891.667692c-12.603077 0-25.206154-2.363077-37.809231-7.876923-37.021538-14.966154-59.864615-49.624615-59.864615-89.009231v-275.692307c0-212.676923 173.292308-385.969231 385.969231-385.969231h78.76923c212.676923 0 385.969231 173.292308 385.969231 385.969231 0 169.353846-137.846154 307.2-307.2 307.2H289.083077l-37.021539 37.021538c-18.904615 18.116923-43.323077 28.356923-67.741538 28.356923zM472.615385 195.347692c-178.018462 0-322.953846 144.935385-322.953847 322.953846v275.692308c0 21.267692 15.753846 29.144615 20.48 31.507692 4.726154 2.363077 22.055385 7.876923 37.021539-7.08923l46.473846-46.473846c6.301538-6.301538 14.178462-9.452308 22.055385-9.452308h354.461538c134.695385 0 244.184615-109.489231 244.184616-244.184616 0-178.018462-144.935385-322.953846-322.953847-322.953846H472.615385z"></path><path d="M321.378462 512m-59.076924 0a59.076923 59.076923 0 1 0 118.153847 0 59.076923 59.076923 0 1 0-118.153847 0Z"></path><path d="M518.301538 512m-59.076923 0a59.076923 59.076923 0 1 0 118.153847 0 59.076923 59.076923 0 1 0-118.153847 0Z"></path><path d="M715.224615 512m-59.076923 0a59.076923 59.076923 0 1 0 118.153846 0 59.076923 59.076923 0 1 0-118.153846 0Z"></path></svg></span><div class="talk-wrap"><ul class="talk-list">`;
var bbAfter = `</ul></div>`;
bbDom.innerHTML = bbBefore + result + bbAfter;
// 克隆第一条追加到末尾,实现无缝循环
var ul = bbDom.querySelector('.talk-list');
if (itemCount > 1) {
ul.appendChild(ul.firstElementChild.cloneNode(true));
}
// 初始化相对时间
requestAnimationFrame(function () {
window.Lately && Lately.init({ target: '.datetime' });
});
// 启动自动滚动
startAutoScroll();
// 鼠标悬停暂停
var wrap = bbDom.querySelector('.talk-wrap');
wrap.addEventListener('mouseenter', stopAutoScroll);
wrap.addEventListener('mouseleave', startAutoScroll);
// 滚轮手动滚动后重置计时器
wrap.addEventListener('wheel', function (e) {
e.preventDefault();
if (e.deltaY > 0) {
scrollToNext();
} else {
scrollToPrev();
}
resetTimer();
});
});
}
// 滚动到下一条
function scrollToNext() {
var wrap = bbDom.querySelector('.talk-wrap');
var itemHeight = wrap.querySelector('li').offsetHeight;
currentIndex++;
wrap.scrollTo({ top: currentIndex * itemHeight, behavior: 'smooth' });
// 滚到克隆的最后一条时,动画结束后瞬间跳回第一条
if (currentIndex >= itemCount) {
setTimeout(function () {
wrap.style.scrollBehavior = 'auto';
wrap.scrollTop = 0;
currentIndex = 0;
// 下一帧恢复平滑滚动
requestAnimationFrame(function () {
wrap.style.scrollBehavior = '';
});
}, 450);
}
}
// 滚动到上一条
function scrollToPrev() {
var wrap = bbDom.querySelector('.talk-wrap');
var itemHeight = wrap.querySelector('li').offsetHeight;
currentIndex--;
if (currentIndex < 0) {
currentIndex = itemCount - 1;
}
wrap.scrollTo({ top: currentIndex * itemHeight, behavior: 'smooth' });
}
// 启动自动滚动
function startAutoScroll() {
if (itemCount <= 1) return;
stopAutoScroll();
timer = setInterval(scrollToNext, 5000);
}
// 停止自动滚动
function stopAutoScroll() {
if (timer) {
clearInterval(timer);
timer = null;
}
}
// 重置计时器
function resetTimer() {
stopAutoScroll();
timer = setInterval(scrollToNext, 5000);
}
memoTalks();
});
创建 CSS 文件
/* ===== 说说模块容器 ===== */
#memos-say {
display: flex;
align-items: center;
background: var(--main-bg-color);
border-radius: var(--main-radius);
padding: 0 12px;
margin-bottom: 15px;
border: 1px solid var(--main-border-color);
height: 44px;
box-sizing: border-box;
}
/* ===== 左侧图标 ===== */
.index-talk-icon {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
margin-right: 8px;
color: var(--theme-color);
}
.index-talk-icon svg {
width: 18px;
height: 18px;
}
/* ===== 滚动容器 ===== */
.talk-wrap {
flex: 1;
height: 34px;
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
scroll-snap-type: y mandatory;
scrollbar-width: none;
-ms-overflow-style: none;
}
.talk-wrap::-webkit-scrollbar {
display: none;
}
/* ===== 说说列表 ===== */
.talk-list {
list-style: none;
margin: 0;
padding: 0;
}
.talk-list li {
list-style: none;
margin: 0;
padding: 0;
height: 34px;
line-height: 34px;
scroll-snap-align: start;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 14px;
color: var(--main-color);
}
/* ===== 时间样式 ===== */
.talk-list .datetime {
color: var(--muted-color);
font-size: 13px;
margin-right: 8px;
}
/* ===== 链接样式 ===== */
.talk-list li a {
color: var(--main-color);
text-decoration: none;
transition: color 0.2s;
}
.talk-list li a:hover {
color: var(--theme-color);
text-decoration: none;
}
/* ===== 深色模式适配 ===== */
.dark-theme #memos-say,
[data-theme="dark"] #memos-say,
:root.dark #memos-say {
background-color: var(--main-bg-color);
border-color: var(--main-border-color);
}
/* ===== 响应式 ===== */
@media (max-width: 768px) {
#memos-say {
margin-bottom: 12px;
height: 40px;
}
.talk-wrap {
height: 30px;
}
.talk-list li {
height: 30px;
line-height: 30px;
font-size: 13px;
}
}
CSS 请根据自己的主题等修改。
创建 CSS 选择器
在你需要的地方创建 CSS 选择器,并引入 CSS 和 JS 文件
<div id="memos-say"></div>
<link rel="stylesheet" href="https://cdn.kaiqi.wang/wp-resource/css/say_page.css">
<script src="https://cdn.kaiqi.wang/wp-resource/js/lately.min.js"></script>
<script type="text/javascript" src="https://cdn.kaiqi.wang/wp-resource/js/say_page.js"></script>
lately.min.js 这个文件是用来显示相对时间,不引入也可以,这样的话就显示实际的发文时间(把文件替换为自己的文件地址)
WordPress 博客下添加
这个设置只针对 WordPress + 子比主题,其他的应该也大同小异。
![图片[1] - Memos 公告样式展示 - 云晓晨 KaiQi.Wang](https://cdn.kaiqi.wang/wp-content/uploads/2025/08/96af77f54220250814184127.webp)
只需在首页合适位置添加 自定义HTML代码 并复制 步骤三 代码,大功告成。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END














暂无评论内容