Memos 公告样式展示

其实刚开始部署 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

只需在首页合适位置添加 自定义HTML代码 并复制 步骤三 代码,大功告成。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像 - 云晓晨 KaiQi.Wang
欢迎您留下宝贵的见解!
提交
头像 - 云晓晨 KaiQi.Wang

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容