![图片[1]-memos 使用指南:自建一个备忘录中心服务-大海博客](https://www.dhme.cn/wp-content/uploads/2023/05/747fffa0d4020020-1024x574.jpg)
不知道小伙伴们平时有没有写日记的习惯?虽说这年头正经人都不写日记了,但我们每天要处理各种各样的事情,一本备忘录还是有必要的。
这类应用其实有很多,我自己也体验过一些。有的集成了许多花里胡哨的功能;有的则是充斥着各种广告。于是我寻思着,那还不如自建一个服务来得直接。
项目介绍
memos[1] 是一个开源、自托管的备忘录中心,项目基于 Golang 和 TypeScript 开发。本文将介绍 memos 的安装和使用方法。
可以说是支持 Docker 自部署的 flomo ,而且有 API 调取数据和发 Memos 。
部署及更新代码
推荐使用 docker-compose.yml
部署,方便制定数据储存位置及更新版本,其中使用 ${PWD}
指定路径为当前文件夹。
version: "3.0"services:memos:image: neosmemo/memos:latestcontainer_name: memosvolumes:- ${PWD}/.memos/:/var/opt/memosports:- 5230:5230version: "3.0" services: memos: image: neosmemo/memos:latest container_name: memos volumes: - ${PWD}/.memos/:/var/opt/memos ports: - 5230:5230version: "3.0" services: memos: image: neosmemo/memos:latest container_name: memos volumes: - ${PWD}/.memos/:/var/opt/memos ports: - 5230:5230
![图片[2]-memos 使用指南:自建一个备忘录中心服务-大海博客](https://www.dhme.cn/wp-content/uploads/2023/05/7e02372c52020255.jpg)
宝塔为例:新建网站,新建 yml,开终端,丢代码。
docker-compose up -ddocker-compose up -ddocker-compose up -d
版本更新也是 一行代码 搞定:
docker-compose pull && docker-compose up -d --force-recreatedocker-compose pull && docker-compose up -d --force-recreatedocker-compose pull && docker-compose up -d --force-recreate
当然,也可以官方的一句拉起 Docker。之后更新需要先去 docker 管理器里删除镜像,再输入下句拉起服务。
docker run -d --name memos -p 5230:5230 -v ${PWD}/.memos/:/var/opt/memos neosmemo/memos:latestdocker run -d --name memos -p 5230:5230 -v ${PWD}/.memos/:/var/opt/memos neosmemo/memos:latestdocker run -d --name memos -p 5230:5230 -v ${PWD}/.memos/:/var/opt/memos neosmemo/memos:latest
注意不定时备份网址目录下的 .memos
文件夹,所有数据都在这。
添加反代
操作如下:在宝塔面版 新建网站
-> 设置
-> 反代
-> 添加代理
-> 设置名称和目标url即可
。如下图:
![图片[3]-memos 使用指南:自建一个备忘录中心服务-大海博客](https://www.dhme.cn/wp-content/uploads/2023/05/076297c70c020657-1024x733.webp)
使用指南
其实很容易搞懂基础的使用,如下图所示:
更多的就自己研究研究吧。
![图片[4]-memos 使用指南:自建一个备忘录中心服务-大海博客](https://www.dhme.cn/wp-content/uploads/2023/05/28e3431d0b020948.webp)
获取api地址
下面节中所提到的memos api地址
格式如下:
https://memos网址/api/memo?creatorId=用户ID&tag=标签名&limit=限制数量https://memos网址/api/memo?creatorId=用户ID&tag=标签名&limit=限制数量https://memos网址/api/memo?creatorId=用户ID&tag=标签名&limit=限制数量
其中memos地址就是首页地址,如:www.niexiaoliang.love
用户ID的获取方法如下:
![图片[5]-memos 使用指南:自建一个备忘录中心服务-大海博客](https://www.dhme.cn/wp-content/uploads/2023/05/1e77ac956a021347-1024x500.webp)
- 查看URL获取ID
如url是:http://www.niexiaoliang.love/u/1
则creatorId就是1
最后完整链接如下:
http://www.niexiaoliang.love/api/memo?creatorId=1&tag=说说&limit=10
能看到数据则为正确链接
说说功能
首先说明,这一切只是我定的规则而已,且功能不多。
你可以随意修改代码来实现你想实现的效果。
懒加载问题
打开文件 [blogroot]\themes\butterfly\scripts\filters\post_lazyload.js
,将第13行的
return htmlContent.replace(/(<img.*? src=)/ig, `$1 "${bg}" data-lazy-src=`)return htmlContent.replace(/(<img.*? src=)/ig, `$1 "${bg}" data-lazy-src=`)return htmlContent.replace(/(<img.*? src=)/ig, `$1 "${bg}" data-lazy-src=`)
修改为
return htmlContent.replace(/(<img(?!.*?class[\t]*=[\t]*['"].*?no-lazyload.*?['"]).*? src=)/gi, `$1 "${bg}" data-lazy-src=`);return htmlContent.replace(/(<img(?!.*?class[\t]*=[\t]*['"].*?no-lazyload.*?['"]).*? src=)/gi, `$1 "${bg}" data-lazy-src=`);return htmlContent.replace(/(<img(?!.*?class[\t]*=[\t]*['"].*?no-lazyload.*?['"]).*? src=)/gi, `$1 "${bg}" data-lazy-src=`);
实现
首先通过hexo n page xxx
创建页面,相信都很熟悉了。
然后粘贴如下代码并按照注释修改内容。
<style>/* 页面初始化 */div#page {background: none;border: 0;padding: 0;}[data-theme=dark] #twikoo .tk-content,#twikoo .tk-content {padding: 0;background: transparent;}.talk_item,.tk-expand,.tk-comments-container>.tk-comment,.tk-submit:nth-child(1){background: var(--card-bg);border: 1px solid #e0e3ed;box-shadow: 0 5px 10px rgb(189 189 189 / 10%);transition: all .3s ease-in-out;border-radius: 12px;}.talk_item:hover,.tk-comments-container>.tk-comment:hover,.tk-submit:nth-child(1):hover {border-color: #49b1f5;}.tk-submit {padding: 20px 10px 0;}.tk-comments-container>.tk-comment {padding: 15px;}/* 页面初始化结束 */#talk{margin-top: 1rem;}#talk .loading {display: flex;align-items: center;justify-content: center;flex-direction: column;}#talk .loading img {width: 200px;}.talk_item {display: flex;flex-direction: column;padding: 20px;margin-bottom: 15px;}.avatar {margin: 0 !important;width: 60px;height: 60px;border-radius: 10px;}.talk_bottom,.talk_meta {display: flex;align-items: center;width: 100%;line-height: 1.5;}.talk_bottom{justify-content: space-between;}.info {display: flex;flex-direction: column;margin-left: 10px;}span.talk_nick {color: #6dbdc3;font-size: 1.2rem;}svg.is-badge.icon {width: 15px;margin-left: 5px;padding-top: 3px;}span.talk_date {opacity: .6;}.talk_content {line-height: 1.5;margin-top: 10px;}.zone_imgbox {display: flex;flex-wrap: wrap;--w: calc(25% - 8px);gap: 10px;margin-top: 5px;}.zone_imgbox a {display: block;border-radius: 12px;width: var(--w);aspect-ratio: 1/1;position: relative;}.zone_imgbox img {width: 100%;height: 100%;margin: 0 !important;object-fit: cover;}/* 底部 */.talk_bottom {opacity: .9;}.talk_bottom .icon {color: var(--font-color);float: right;transition: all .3s;}.talk_bottom .icon:hover {color: #49b1f5;}span.talk_tag{font-size: 14px;}.talk_content>a {margin: 0 3px;color: #ff7d73 !important;}.talk_content>a:hover{text-decoration: none !important;color: #ff5143 !important}/* 提醒 */.limit {transition: all .3s ease-in-out;color: rgba(76, 73, 72, 0.6);}[data-theme=dark] .limit {color: rgba(255, 255, 255, 0.5);}.limit {display: none;text-align: center;margin-top: 20px;color: var(--font-color);}@media screen and (max-width: 900px) {.zone_imgbox {--w: calc(33% - 5px);}#talk{margin: 10px 3px 0}#post-comment{margin: 0 3px}}@media screen and (max-width: 768px) {.zone_imgbox {gap: 6px;}.zone_imgbox {--w: calc(50% - 3px);}span.talk_date {font-size: 14px;}}</style><div id="talk"><div class='loading'><img src="/img/loading.svg" alt="加载中..."></div></div><div class="limit">- 只展示最近30条说说 -</div><script>pageTalk();// 页面说说function pageTalk() {fetch('https://你的memos地址/api/memo?creatorId=你的ID&tag=说说&limit=30').then(res => res.json()).then(data => { // 注意修改域名和用户idlet items = [],html = '',icon = '<svg viewBox="0 0 512 512"xmlns="http://www.w3.org/2000/svg"class="is-badge icon"><path d="m512 268c0 17.9-4.3 34.5-12.9 49.7s-20.1 27.1-34.6 35.4c.4 2.7.6 6.9.6 12.6 0 27.1-9.1 50.1-27.1 69.1-18.1 19.1-39.9 28.6-65.4 28.6-11.4 0-22.3-2.1-32.6-6.3-8 16.4-19.5 29.6-34.6 39.7-15 10.2-31.5 15.2-49.4 15.2-18.3 0-34.9-4.9-49.7-14.9-14.9-9.9-26.3-23.2-34.3-40-10.3 4.2-21.1 6.3-32.6 6.3-25.5 0-47.4-9.5-65.7-28.6-18.3-19-27.4-42.1-27.4-69.1 0-3 .4-7.2 1.1-12.6-14.5-8.4-26-20.2-34.6-35.4-8.5-15.2-12.8-31.8-12.8-49.7 0-19 4.8-36.5 14.3-52.3s22.3-27.5 38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3 0-27 9.1-50.1 27.4-69.1s40.2-28.6 65.7-28.6c11.4 0 22.3 2.1 32.6 6.3 8-16.4 19.5-29.6 34.6-39.7 15-10.1 31.5-15.2 49.4-15.2s34.4 5.1 49.4 15.1c15 10.1 26.6 23.3 34.6 39.7 10.3-4.2 21.1-6.3 32.6-6.3 25.5 0 47.3 9.5 65.4 28.6s27.1 42.1 27.1 69.1c0 12.6-1.9 24-5.7 34.3 16 7.6 28.8 19.3 38.3 35.1 9.5 15.9 14.3 33.4 14.3 52.4zm-266.9 77.1 105.7-158.3c2.7-4.2 3.5-8.8 2.6-13.7-1-4.9-3.5-8.8-7.7-11.4-4.2-2.7-8.8-3.6-13.7-2.9-5 .8-9 3.2-12 7.4l-93.1 140-42.9-42.8c-3.8-3.8-8.2-5.6-13.1-5.4-5 .2-9.3 2-13.1 5.4-3.4 3.4-5.1 7.7-5.1 12.9 0 5.1 1.7 9.4 5.1 12.9l58.9 58.9 2.9 2.3c3.4 2.3 6.9 3.4 10.3 3.4 6.7-.1 11.8-2.9 15.2-8.7z"fill="#1da1f2"></path></svg>';data.data.forEach(item => { items.push(Format(item)) });if (items.length == 30) document.querySelector('.limit').style.display = 'block';items.forEach(item => {html += `<div class="talk_item"><div class="talk_meta"><img class="no-lightbox no-lazyload avatar" src="https://q1.qlogo.cn/g?b=qq&nk=990320751&s=5"><div class="info"><span class="talk_nick">Leonus${icon}</span><span class="talk_date">${item.date}</span></div></div><div class="talk_content">${item.content}</div><div class="talk_bottom"><div><span class="talk_tag"># ${item.tag}</span></div><a href="javascript:;"onclick="goComment('${item.text}')"><span class="icon"><i class="fa-solid fa-message fa-fw"></i></span></a></div></div>` // 注意修改头像链接和名称})document.getElementById('talk').innerHTML = html})}// 页面评论function goComment(e) {var n = document.querySelector(".el-textarea__inner")n.value = `> ${e}\n\n`;n.focus();btf.snackbarShow("无需删除空行,直接输入评论即可", !1, 2e3);}// 页面内容格式化function Format(item) {let date = getTime(new Date(item.createdTs * 1000).toString()),content = item.content,tag = item.content.match(/\{(.*?)\}/g),imgls = content.match(/!\[.*\]\(.*?\)/g), // 2023-02-06更新text = ''text = content.replace(/#(.*?)\s/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '')content = text.replace(/\[(.*?)\]\((.*?)\)/g, `<a href="$2">@$1</a>`);if (imgls) {content += `<div class="zone_imgbox">`imgls.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1') }).forEach(e => content += `<a href="${e}" data-fancybox="gallery" class="fancybox" data-thumb="${e}"><img class="no-lazyload" src="${e}"></a>` // 2023-02-06更新)content += '</div>'}return {content: content,tag: tag ? tag[0].replace(/\{(.*?)\}/,'$1') : '无标签',date: date,text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgls?'[图片]':''}`)}}// 页面时间格式化function getTime(time) {let d = new Date(time),ls = [d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()];for (let i = 0; i < ls.length; i++) {ls[i] = ls[i] <= 9 ? '0' + ls[i] : ls[i] + ''}if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]}</script><style> /* 页面初始化 */ div#page { background: none; border: 0; padding: 0; } [data-theme=dark] #twikoo .tk-content, #twikoo .tk-content { padding: 0; background: transparent; } .talk_item, .tk-expand, .tk-comments-container>.tk-comment, .tk-submit:nth-child(1){ background: var(--card-bg); border: 1px solid #e0e3ed; box-shadow: 0 5px 10px rgb(189 189 189 / 10%); transition: all .3s ease-in-out; border-radius: 12px; } .talk_item:hover, .tk-comments-container>.tk-comment:hover, .tk-submit:nth-child(1):hover { border-color: #49b1f5; } .tk-submit { padding: 20px 10px 0; } .tk-comments-container>.tk-comment { padding: 15px; } /* 页面初始化结束 */ #talk{ margin-top: 1rem; } #talk .loading { display: flex; align-items: center; justify-content: center; flex-direction: column; } #talk .loading img { width: 200px; } .talk_item { display: flex; flex-direction: column; padding: 20px; margin-bottom: 15px; } .avatar { margin: 0 !important; width: 60px; height: 60px; border-radius: 10px; } .talk_bottom, .talk_meta { display: flex; align-items: center; width: 100%; line-height: 1.5; } .talk_bottom{ justify-content: space-between; } .info { display: flex; flex-direction: column; margin-left: 10px; } span.talk_nick { color: #6dbdc3; font-size: 1.2rem; } svg.is-badge.icon { width: 15px; margin-left: 5px; padding-top: 3px; } span.talk_date { opacity: .6; } .talk_content { line-height: 1.5; margin-top: 10px; } .zone_imgbox { display: flex; flex-wrap: wrap; --w: calc(25% - 8px); gap: 10px; margin-top: 5px; } .zone_imgbox a { display: block; border-radius: 12px; width: var(--w); aspect-ratio: 1/1; position: relative; } .zone_imgbox img { width: 100%; height: 100%; margin: 0 !important; object-fit: cover; } /* 底部 */ .talk_bottom { opacity: .9; } .talk_bottom .icon { color: var(--font-color); float: right; transition: all .3s; } .talk_bottom .icon:hover { color: #49b1f5; } span.talk_tag{ font-size: 14px; } .talk_content>a { margin: 0 3px; color: #ff7d73 !important; } .talk_content>a:hover{ text-decoration: none !important; color: #ff5143 !important } /* 提醒 */ .limit { transition: all .3s ease-in-out; color: rgba(76, 73, 72, 0.6); } [data-theme=dark] .limit { color: rgba(255, 255, 255, 0.5); } .limit { display: none; text-align: center; margin-top: 20px; color: var(--font-color); } @media screen and (max-width: 900px) { .zone_imgbox { --w: calc(33% - 5px); } #talk{ margin: 10px 3px 0 } #post-comment{ margin: 0 3px } } @media screen and (max-width: 768px) { .zone_imgbox { gap: 6px; } .zone_imgbox { --w: calc(50% - 3px); } span.talk_date { font-size: 14px; } } </style> <div id="talk"> <div class='loading'><img src="/img/loading.svg" alt="加载中..."></div> </div> <div class="limit">- 只展示最近30条说说 -</div> <script> pageTalk(); // 页面说说 function pageTalk() { fetch('https://你的memos地址/api/memo?creatorId=你的ID&tag=说说&limit=30').then(res => res.json()).then(data => { // 注意修改域名和用户id let items = [], html = '', icon = '<svg viewBox="0 0 512 512"xmlns="http://www.w3.org/2000/svg"class="is-badge icon"><path d="m512 268c0 17.9-4.3 34.5-12.9 49.7s-20.1 27.1-34.6 35.4c.4 2.7.6 6.9.6 12.6 0 27.1-9.1 50.1-27.1 69.1-18.1 19.1-39.9 28.6-65.4 28.6-11.4 0-22.3-2.1-32.6-6.3-8 16.4-19.5 29.6-34.6 39.7-15 10.2-31.5 15.2-49.4 15.2-18.3 0-34.9-4.9-49.7-14.9-14.9-9.9-26.3-23.2-34.3-40-10.3 4.2-21.1 6.3-32.6 6.3-25.5 0-47.4-9.5-65.7-28.6-18.3-19-27.4-42.1-27.4-69.1 0-3 .4-7.2 1.1-12.6-14.5-8.4-26-20.2-34.6-35.4-8.5-15.2-12.8-31.8-12.8-49.7 0-19 4.8-36.5 14.3-52.3s22.3-27.5 38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3 0-27 9.1-50.1 27.4-69.1s40.2-28.6 65.7-28.6c11.4 0 22.3 2.1 32.6 6.3 8-16.4 19.5-29.6 34.6-39.7 15-10.1 31.5-15.2 49.4-15.2s34.4 5.1 49.4 15.1c15 10.1 26.6 23.3 34.6 39.7 10.3-4.2 21.1-6.3 32.6-6.3 25.5 0 47.3 9.5 65.4 28.6s27.1 42.1 27.1 69.1c0 12.6-1.9 24-5.7 34.3 16 7.6 28.8 19.3 38.3 35.1 9.5 15.9 14.3 33.4 14.3 52.4zm-266.9 77.1 105.7-158.3c2.7-4.2 3.5-8.8 2.6-13.7-1-4.9-3.5-8.8-7.7-11.4-4.2-2.7-8.8-3.6-13.7-2.9-5 .8-9 3.2-12 7.4l-93.1 140-42.9-42.8c-3.8-3.8-8.2-5.6-13.1-5.4-5 .2-9.3 2-13.1 5.4-3.4 3.4-5.1 7.7-5.1 12.9 0 5.1 1.7 9.4 5.1 12.9l58.9 58.9 2.9 2.3c3.4 2.3 6.9 3.4 10.3 3.4 6.7-.1 11.8-2.9 15.2-8.7z"fill="#1da1f2"></path></svg>'; data.data.forEach(item => { items.push(Format(item)) }); if (items.length == 30) document.querySelector('.limit').style.display = 'block'; items.forEach(item => { html += `<div class="talk_item"><div class="talk_meta"><img class="no-lightbox no-lazyload avatar" src="https://q1.qlogo.cn/g?b=qq&nk=990320751&s=5"><div class="info"><span class="talk_nick">Leonus${icon}</span><span class="talk_date">${item.date}</span></div></div><div class="talk_content">${item.content}</div><div class="talk_bottom"><div><span class="talk_tag"># ${item.tag}</span></div><a href="javascript:;"onclick="goComment('${item.text}')"><span class="icon"><i class="fa-solid fa-message fa-fw"></i></span></a></div></div>` // 注意修改头像链接和名称 }) document.getElementById('talk').innerHTML = html }) } // 页面评论 function goComment(e) { var n = document.querySelector(".el-textarea__inner") n.value = `> ${e}\n\n`; n.focus(); btf.snackbarShow("无需删除空行,直接输入评论即可", !1, 2e3); } // 页面内容格式化 function Format(item) { let date = getTime(new Date(item.createdTs * 1000).toString()), content = item.content, tag = item.content.match(/\{(.*?)\}/g), imgls = content.match(/!\[.*\]\(.*?\)/g), // 2023-02-06更新 text = '' text = content.replace(/#(.*?)\s/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '') content = text.replace(/\[(.*?)\]\((.*?)\)/g, `<a href="$2">@$1</a>`); if (imgls) { content += `<div class="zone_imgbox">` imgls.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1') }).forEach(e => content += `<a href="${e}" data-fancybox="gallery" class="fancybox" data-thumb="${e}"><img class="no-lazyload" src="${e}"></a>` // 2023-02-06更新 ) content += '</div>' } return { content: content, tag: tag ? tag[0].replace(/\{(.*?)\}/,'$1') : '无标签', date: date, text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgls?'[图片]':''}`) } } // 页面时间格式化 function getTime(time) { let d = new Date(time), ls = [d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()]; for (let i = 0; i < ls.length; i++) { ls[i] = ls[i] <= 9 ? '0' + ls[i] : ls[i] + '' } if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4] else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4] } </script><style> /* 页面初始化 */ div#page { background: none; border: 0; padding: 0; } [data-theme=dark] #twikoo .tk-content, #twikoo .tk-content { padding: 0; background: transparent; } .talk_item, .tk-expand, .tk-comments-container>.tk-comment, .tk-submit:nth-child(1){ background: var(--card-bg); border: 1px solid #e0e3ed; box-shadow: 0 5px 10px rgb(189 189 189 / 10%); transition: all .3s ease-in-out; border-radius: 12px; } .talk_item:hover, .tk-comments-container>.tk-comment:hover, .tk-submit:nth-child(1):hover { border-color: #49b1f5; } .tk-submit { padding: 20px 10px 0; } .tk-comments-container>.tk-comment { padding: 15px; } /* 页面初始化结束 */ #talk{ margin-top: 1rem; } #talk .loading { display: flex; align-items: center; justify-content: center; flex-direction: column; } #talk .loading img { width: 200px; } .talk_item { display: flex; flex-direction: column; padding: 20px; margin-bottom: 15px; } .avatar { margin: 0 !important; width: 60px; height: 60px; border-radius: 10px; } .talk_bottom, .talk_meta { display: flex; align-items: center; width: 100%; line-height: 1.5; } .talk_bottom{ justify-content: space-between; } .info { display: flex; flex-direction: column; margin-left: 10px; } span.talk_nick { color: #6dbdc3; font-size: 1.2rem; } svg.is-badge.icon { width: 15px; margin-left: 5px; padding-top: 3px; } span.talk_date { opacity: .6; } .talk_content { line-height: 1.5; margin-top: 10px; } .zone_imgbox { display: flex; flex-wrap: wrap; --w: calc(25% - 8px); gap: 10px; margin-top: 5px; } .zone_imgbox a { display: block; border-radius: 12px; width: var(--w); aspect-ratio: 1/1; position: relative; } .zone_imgbox img { width: 100%; height: 100%; margin: 0 !important; object-fit: cover; } /* 底部 */ .talk_bottom { opacity: .9; } .talk_bottom .icon { color: var(--font-color); float: right; transition: all .3s; } .talk_bottom .icon:hover { color: #49b1f5; } span.talk_tag{ font-size: 14px; } .talk_content>a { margin: 0 3px; color: #ff7d73 !important; } .talk_content>a:hover{ text-decoration: none !important; color: #ff5143 !important } /* 提醒 */ .limit { transition: all .3s ease-in-out; color: rgba(76, 73, 72, 0.6); } [data-theme=dark] .limit { color: rgba(255, 255, 255, 0.5); } .limit { display: none; text-align: center; margin-top: 20px; color: var(--font-color); } @media screen and (max-width: 900px) { .zone_imgbox { --w: calc(33% - 5px); } #talk{ margin: 10px 3px 0 } #post-comment{ margin: 0 3px } } @media screen and (max-width: 768px) { .zone_imgbox { gap: 6px; } .zone_imgbox { --w: calc(50% - 3px); } span.talk_date { font-size: 14px; } } </style> <div id="talk"> <div class='loading'><img src="/img/loading.svg" alt="加载中..."></div> </div> <div class="limit">- 只展示最近30条说说 -</div> <script> pageTalk(); // 页面说说 function pageTalk() { fetch('https://你的memos地址/api/memo?creatorId=你的ID&tag=说说&limit=30').then(res => res.json()).then(data => { // 注意修改域名和用户id let items = [], html = '', icon = '<svg viewBox="0 0 512 512"xmlns="http://www.w3.org/2000/svg"class="is-badge icon"><path d="m512 268c0 17.9-4.3 34.5-12.9 49.7s-20.1 27.1-34.6 35.4c.4 2.7.6 6.9.6 12.6 0 27.1-9.1 50.1-27.1 69.1-18.1 19.1-39.9 28.6-65.4 28.6-11.4 0-22.3-2.1-32.6-6.3-8 16.4-19.5 29.6-34.6 39.7-15 10.2-31.5 15.2-49.4 15.2-18.3 0-34.9-4.9-49.7-14.9-14.9-9.9-26.3-23.2-34.3-40-10.3 4.2-21.1 6.3-32.6 6.3-25.5 0-47.4-9.5-65.7-28.6-18.3-19-27.4-42.1-27.4-69.1 0-3 .4-7.2 1.1-12.6-14.5-8.4-26-20.2-34.6-35.4-8.5-15.2-12.8-31.8-12.8-49.7 0-19 4.8-36.5 14.3-52.3s22.3-27.5 38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3 0-27 9.1-50.1 27.4-69.1s40.2-28.6 65.7-28.6c11.4 0 22.3 2.1 32.6 6.3 8-16.4 19.5-29.6 34.6-39.7 15-10.1 31.5-15.2 49.4-15.2s34.4 5.1 49.4 15.1c15 10.1 26.6 23.3 34.6 39.7 10.3-4.2 21.1-6.3 32.6-6.3 25.5 0 47.3 9.5 65.4 28.6s27.1 42.1 27.1 69.1c0 12.6-1.9 24-5.7 34.3 16 7.6 28.8 19.3 38.3 35.1 9.5 15.9 14.3 33.4 14.3 52.4zm-266.9 77.1 105.7-158.3c2.7-4.2 3.5-8.8 2.6-13.7-1-4.9-3.5-8.8-7.7-11.4-4.2-2.7-8.8-3.6-13.7-2.9-5 .8-9 3.2-12 7.4l-93.1 140-42.9-42.8c-3.8-3.8-8.2-5.6-13.1-5.4-5 .2-9.3 2-13.1 5.4-3.4 3.4-5.1 7.7-5.1 12.9 0 5.1 1.7 9.4 5.1 12.9l58.9 58.9 2.9 2.3c3.4 2.3 6.9 3.4 10.3 3.4 6.7-.1 11.8-2.9 15.2-8.7z"fill="#1da1f2"></path></svg>'; data.data.forEach(item => { items.push(Format(item)) }); if (items.length == 30) document.querySelector('.limit').style.display = 'block'; items.forEach(item => { html += `<div class="talk_item"><div class="talk_meta"><img class="no-lightbox no-lazyload avatar" src="https://q1.qlogo.cn/g?b=qq&nk=990320751&s=5"><div class="info"><span class="talk_nick">Leonus${icon}</span><span class="talk_date">${item.date}</span></div></div><div class="talk_content">${item.content}</div><div class="talk_bottom"><div><span class="talk_tag"># ${item.tag}</span></div><a href="javascript:;"onclick="goComment('${item.text}')"><span class="icon"><i class="fa-solid fa-message fa-fw"></i></span></a></div></div>` // 注意修改头像链接和名称 }) document.getElementById('talk').innerHTML = html }) } // 页面评论 function goComment(e) { var n = document.querySelector(".el-textarea__inner") n.value = `> ${e}\n\n`; n.focus(); btf.snackbarShow("无需删除空行,直接输入评论即可", !1, 2e3); } // 页面内容格式化 function Format(item) { let date = getTime(new Date(item.createdTs * 1000).toString()), content = item.content, tag = item.content.match(/\{(.*?)\}/g), imgls = content.match(/!\[.*\]\(.*?\)/g), // 2023-02-06更新 text = '' text = content.replace(/#(.*?)\s/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '') content = text.replace(/\[(.*?)\]\((.*?)\)/g, `<a href="$2">@$1</a>`); if (imgls) { content += `<div class="zone_imgbox">` imgls.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1') }).forEach(e => content += `<a href="${e}" data-fancybox="gallery" class="fancybox" data-thumb="${e}"><img class="no-lazyload" src="${e}"></a>` // 2023-02-06更新 ) content += '</div>' } return { content: content, tag: tag ? tag[0].replace(/\{(.*?)\}/,'$1') : '无标签', date: date, text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgls?'[图片]':''}`) } } // 页面时间格式化 function getTime(time) { let d = new Date(time), ls = [d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()]; for (let i = 0; i < ls.length; i++) { ls[i] = ls[i] <= 9 ? '0' + ls[i] : ls[i] + '' } if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4] else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4] } </script>
使用
使用的格式如下:
#说说 {说说标签} 我是内容 [我是链接](链接地址) #说说 {说说标签} 我是内容 [我是链接](链接地址) #说说 {说说标签} 我是内容 [我是链接](链接地址) 
注意,前面的#说说
是固定的。标签用大括号包起来。
首页说说轮播
修改源码
修改如下源码:[blogroot]\themes\butterfly\layout\includes\layout.pug
,在main(第23行左右)上面添加如下代码。
注意根据注释修改代码中的说说页面地址。
如下图所示:
![图片[6]-memos 使用指南:自建一个备忘录中心服务-大海博客](https://www.dhme.cn/wp-content/uploads/2023/05/5af65b27e3022550-1024x248.webp)
添加css
在自定义css文件中添加如下代码,
/* maintop */div#main_top {z-index: 1;max-width: 1200px;margin: 20px auto -15px;width: 100%;padding: 0 15px;}@media screen and (min-width: 2000px) {div#main_top {max-width: 1500px;}}#bber-talk {border-radius: 12px;box-shadow: none;border: 1px solid #e0e3ed;box-sizing: border-box;transition: all .3s ease-in-out;cursor: pointer;width: 100%;min-height: 50px;background: var(--card-bg);padding: .5rem 1rem;display: flex;align-items: center;overflow: hidden;font-weight: 700;}#bber-talk:hover {border-color: #49b1f5;box-shadow: none;}#bber-talk,#bber-talk a {color: var(--font-color);}#bber-talk svg.icon {width: 1em;height: 1em;vertical-align: -.15em;fill: currentColor;overflow: hidden;font-size: 20px;}#bber-talk .item i {margin-left: 5px;}#bber-talk>i {font-size: 1.1rem;}#bber-talk .talk-list {flex: 1;max-height: 32px;font-size: 16px;padding: 0;margin: 0;overflow: hidden;}#bber-talk .talk-list :hover {color: #49b1f5 !important;transition: all .2s ease-in-out;}#bber-talk .talk-list li {list-style: none;width: 100%;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;margin-left: 10px;}@media screen and (min-width: 768px) {#bber-talk .talk-list {text-align: center;margin-right: 20px;}}/* maintop */ div#main_top { z-index: 1; max-width: 1200px; margin: 20px auto -15px; width: 100%; padding: 0 15px; } @media screen and (min-width: 2000px) { div#main_top { max-width: 1500px; } } #bber-talk { border-radius: 12px; box-shadow: none; border: 1px solid #e0e3ed; box-sizing: border-box; transition: all .3s ease-in-out; cursor: pointer; width: 100%; min-height: 50px; background: var(--card-bg); padding: .5rem 1rem; display: flex; align-items: center; overflow: hidden; font-weight: 700; } #bber-talk:hover { border-color: #49b1f5; box-shadow: none; } #bber-talk, #bber-talk a { color: var(--font-color); } #bber-talk svg.icon { width: 1em; height: 1em; vertical-align: -.15em; fill: currentColor; overflow: hidden; font-size: 20px; } #bber-talk .item i { margin-left: 5px; } #bber-talk>i { font-size: 1.1rem; } #bber-talk .talk-list { flex: 1; max-height: 32px; font-size: 16px; padding: 0; margin: 0; overflow: hidden; } #bber-talk .talk-list :hover { color: #49b1f5 !important; transition: all .2s ease-in-out; } #bber-talk .talk-list li { list-style: none; width: 100%; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; margin-left: 10px; } @media screen and (min-width: 768px) { #bber-talk .talk-list { text-align: center; margin-right: 20px; } }/* maintop */ div#main_top { z-index: 1; max-width: 1200px; margin: 20px auto -15px; width: 100%; padding: 0 15px; } @media screen and (min-width: 2000px) { div#main_top { max-width: 1500px; } } #bber-talk { border-radius: 12px; box-shadow: none; border: 1px solid #e0e3ed; box-sizing: border-box; transition: all .3s ease-in-out; cursor: pointer; width: 100%; min-height: 50px; background: var(--card-bg); padding: .5rem 1rem; display: flex; align-items: center; overflow: hidden; font-weight: 700; } #bber-talk:hover { border-color: #49b1f5; box-shadow: none; } #bber-talk, #bber-talk a { color: var(--font-color); } #bber-talk svg.icon { width: 1em; height: 1em; vertical-align: -.15em; fill: currentColor; overflow: hidden; font-size: 20px; } #bber-talk .item i { margin-left: 5px; } #bber-talk>i { font-size: 1.1rem; } #bber-talk .talk-list { flex: 1; max-height: 32px; font-size: 16px; padding: 0; margin: 0; overflow: hidden; } #bber-talk .talk-list :hover { color: #49b1f5 !important; transition: all .2s ease-in-out; } #bber-talk .talk-list li { list-style: none; width: 100%; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; margin-left: 10px; } @media screen and (min-width: 768px) { #bber-talk .talk-list { text-align: center; margin-right: 20px; } }
添加js
在自定义js文件中添加如下代码,
引入时放在inject的bottom里面,不要放在head里。按照注释修改代码。
为了方便没有添加动画,切换比较生硬(其实本人还挺喜欢的)。可以自行使用swiper等添加动画。
// 存数据function saveData(name, data) { localStorage.setItem(name, JSON.stringify({ 'time': Date.now(), 'data': data })) };// 取数据function loadData(name, time) {let d = JSON.parse(localStorage.getItem(name));// 过期或有错误返回 0 否则返回数据if (d) {let t = Date.now() - d.timeif (-1 < t && t < (time * 60000)) return d.data;}return 0;};let talkTimer = null;function indexTalk() {if (talkTimer) {clearInterval(talkTimer)talkTimer = null;}if (!document.getElementById('bber-talk')) returnfunction toText(ls) {let text = []ls.forEach(item => {text.push(item.content.replace(/#(.*?)\s/g, '').replace(/\{(.*?)\}/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '<i class="fa-solid fa-image"></i>').replace(/\[(.*?)\]\((.*?)\)/g, '<i class="fa-solid fa-link"></i>'))});return text}function talk(ls) {let html = ''ls.forEach((item, i) => { html += `<li class="item item-${i + 1}">${item}</li>` });let box = document.querySelector("#bber-talk .talk-list")box.innerHTML = html;talkTimer = setInterval(() => {box.appendChild(box.children[0]);}, 3000);}let d = loadData('talk', 10);if (d) talk(d);else {fetch('https://你的memos地址/api/memo?creatorId=用户ID&tag=说说&limit=10').then(res => res.json()).then(data => { // 更改地址和IDdata = toText(data.data)talk(data);saveData('talk', data);})}}indexTalk();// pjax注释掉上面的 indexTalk(); 使用如下方法:// function whenDOMReady() {// indexTalk();// }// whenDOMReady()// document.addEventListener("pjax:complete", whenDOMReady)// 存数据 function saveData(name, data) { localStorage.setItem(name, JSON.stringify({ 'time': Date.now(), 'data': data })) }; // 取数据 function loadData(name, time) { let d = JSON.parse(localStorage.getItem(name)); // 过期或有错误返回 0 否则返回数据 if (d) { let t = Date.now() - d.time if (-1 < t && t < (time * 60000)) return d.data; } return 0; }; let talkTimer = null; function indexTalk() { if (talkTimer) { clearInterval(talkTimer) talkTimer = null; } if (!document.getElementById('bber-talk')) return function toText(ls) { let text = [] ls.forEach(item => { text.push(item.content.replace(/#(.*?)\s/g, '').replace(/\{(.*?)\}/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '<i class="fa-solid fa-image"></i>').replace(/\[(.*?)\]\((.*?)\)/g, '<i class="fa-solid fa-link"></i>')) }); return text } function talk(ls) { let html = '' ls.forEach((item, i) => { html += `<li class="item item-${i + 1}">${item}</li>` }); let box = document.querySelector("#bber-talk .talk-list") box.innerHTML = html; talkTimer = setInterval(() => { box.appendChild(box.children[0]); }, 3000); } let d = loadData('talk', 10); if (d) talk(d); else { fetch('https://你的memos地址/api/memo?creatorId=用户ID&tag=说说&limit=10').then(res => res.json()).then(data => { // 更改地址和ID data = toText(data.data) talk(data); saveData('talk', data); }) } } indexTalk(); // pjax注释掉上面的 indexTalk(); 使用如下方法: // function whenDOMReady() { // indexTalk(); // } // whenDOMReady() // document.addEventListener("pjax:complete", whenDOMReady)// 存数据 function saveData(name, data) { localStorage.setItem(name, JSON.stringify({ 'time': Date.now(), 'data': data })) }; // 取数据 function loadData(name, time) { let d = JSON.parse(localStorage.getItem(name)); // 过期或有错误返回 0 否则返回数据 if (d) { let t = Date.now() - d.time if (-1 < t && t < (time * 60000)) return d.data; } return 0; }; let talkTimer = null; function indexTalk() { if (talkTimer) { clearInterval(talkTimer) talkTimer = null; } if (!document.getElementById('bber-talk')) return function toText(ls) { let text = [] ls.forEach(item => { text.push(item.content.replace(/#(.*?)\s/g, '').replace(/\{(.*?)\}/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '<i class="fa-solid fa-image"></i>').replace(/\[(.*?)\]\((.*?)\)/g, '<i class="fa-solid fa-link"></i>')) }); return text } function talk(ls) { let html = '' ls.forEach((item, i) => { html += `<li class="item item-${i + 1}">${item}</li>` }); let box = document.querySelector("#bber-talk .talk-list") box.innerHTML = html; talkTimer = setInterval(() => { box.appendChild(box.children[0]); }, 3000); } let d = loadData('talk', 10); if (d) talk(d); else { fetch('https://你的memos地址/api/memo?creatorId=用户ID&tag=说说&limit=10').then(res => res.json()).then(data => { // 更改地址和ID data = toText(data.data) talk(data); saveData('talk', data); }) } } indexTalk(); // pjax注释掉上面的 indexTalk(); 使用如下方法: // function whenDOMReady() { // indexTalk(); // } // whenDOMReady() // document.addEventListener("pjax:complete", whenDOMReady)
清单功能
再次说明,这一切只是我定的规则而已,你可以随意修改代码来实现你想实现的效果。
实现
还是先使用hexo n page xxx
创建页面。
然后粘贴如下代码并按照注释修改内容。
<style>/* 页面初始化 */div#page {background: none;border: 0;padding: 0;}[data-theme=dark] #twikoo .tk-content,#twikoo .tk-content {padding: 0;background: transparent;}.tk-comments-container>.tk-comment,.tk-submit:nth-child(1){background: var(--card-bg);border: 1px rgba(188, 188, 188, 0.8) solid;box-shadow: 0 5px 10px rgb(189 189 189 / 10%);transition: all .3s ease-in-out;border-radius: 12px;}.tk-comments-container>.tk-comment:hover,.tk-submit:nth-child(1):hover {border-color: #6dc3fd;}.tk-submit {padding: 20px 10px 0;}.tk-comments-container>.tk-comment {padding: 15px;}/* 页面初始化结束 */div#todolist {display: flex;flex-wrap: wrap;margin-top: 1rem;}.list_item {display: inline-block;width: calc(50% - .4rem);background: #ffe3dd;border-radius: 12px;padding: 10px 1rem 1.2rem;border: 2px dashed #f7a796;--todo-border: 1px solid #f7a796;margin-right: 1rem;margin-bottom: 1rem;}.list_item h3 {margin: 0;border-bottom: var(--todo-border);}.list_item ul {font-size: 17px;padding: 0 !important;margin: 0;}.list_item li{margin: 0 !important;border-bottom: var(--todo-border);}.list_item li::marker {content: none;}li.achieve {opacity: .8;text-decoration: line-through;}@media screen and (max-width: 900px) {div#todolist {margin: 1rem 5px 0;}}@media screen and (max-width: 768px) {.list_item{width: 100%;}}</style><div id="todolist"></div><script>// 瀑布流函数,不用管function waterfall(t){function e(t,e){var n=window.getComputedStyle(e);return parseFloat(n["margin"+t])||0}function n(t){return t+"px"}function r(t){return parseFloat(t.style.left)}function o(t){return t.clientWidth}function l(t){return function(t){return parseFloat(t.style.top)}(t)+function(t){return t.clientHeight}(t)+e("Bottom",t)}function i(t){return r(t)+o(t)+e("Right",t)}function u(t){t=t.sort((function(t,e){return l(t)===l(e)?r(e)-r(t):l(e)-l(t)}))}function a(e){o(t)!=h&&(e.target.removeEventListener(e.type,arguments.callee),waterfall(t))}"string"==typeof t&&(t=document.querySelector(t));var s=[].map.call(t.children,(function(t){return t.style.position="absolute",t}));t.style.position="relative";var f=[];s.length&&(s[0].style.top="0px",s[0].style.left=n(e("Left",s[0])),f.push(s[0]));for(var p=1;p<s.length;p++){var c=s[p-1],y=s[p];if(!(i(c)+o(y)<=o(t)))break;y.style.top=c.style.top,y.style.left=n(i(c)+e("Left",y)),f.push(y)}for(;p<s.length;p++){u(f);y=s[p];var d=f.pop();y.style.top=n(l(d)+e("Top",y)),y.style.left=n(r(d)),f.push(y)}u(f);var v=f[0];t.style.height=n(l(v));var h=o(t);window.addEventListener?window.addEventListener("resize",a):document.body.onresize=a}// 清单函数todolist();function todolist() {fetch('https://你的memos地址/api/memo?creatorId=用户ID&tag=清单').then(res => res.json()).then(data => { // 注意替换链接和ID// 获取并处理数据data = data.datalet box = document.getElementById('todolist')data.forEach(item => {// 处理数据let content = item.content,title = content.match(/\[(.*?)\]/g)[0].replace(/\[(.*?)\]/,'$1');// 去掉多余内容,替换清单内容content = content.replace(/#.*\s/g, '').replace(/(-\s\[\s\]\s)(.*)/g, `<li><i style="margin-right: 5px;" class="fa-regular fa-circle"></i>$2</li>`).replace(/(-\s\[x\]\s)(.*)/g, `<li class="achieve"><i style="margin-right: 5px;" class="fa-regular fa-circle-check"></i>$2</li>`);// 渲染数据let div = document.createElement('div');div.className = 'list_item';div.innerHTML = `<h3>${title}</h3><ul>${content}</ul>`;box.appendChild(div);});waterfall('#todolist');}).catch()}</script><style> /* 页面初始化 */ div#page { background: none; border: 0; padding: 0; } [data-theme=dark] #twikoo .tk-content, #twikoo .tk-content { padding: 0; background: transparent; } .tk-comments-container>.tk-comment, .tk-submit:nth-child(1){ background: var(--card-bg); border: 1px rgba(188, 188, 188, 0.8) solid; box-shadow: 0 5px 10px rgb(189 189 189 / 10%); transition: all .3s ease-in-out; border-radius: 12px; } .tk-comments-container>.tk-comment:hover, .tk-submit:nth-child(1):hover { border-color: #6dc3fd; } .tk-submit { padding: 20px 10px 0; } .tk-comments-container>.tk-comment { padding: 15px; } /* 页面初始化结束 */ div#todolist { display: flex; flex-wrap: wrap; margin-top: 1rem; } .list_item { display: inline-block; width: calc(50% - .4rem); background: #ffe3dd; border-radius: 12px; padding: 10px 1rem 1.2rem; border: 2px dashed #f7a796; --todo-border: 1px solid #f7a796; margin-right: 1rem; margin-bottom: 1rem; } .list_item h3 { margin: 0; border-bottom: var(--todo-border); } .list_item ul { font-size: 17px; padding: 0 !important; margin: 0; } .list_item li{ margin: 0 !important; border-bottom: var(--todo-border); } .list_item li::marker { content: none; } li.achieve { opacity: .8; text-decoration: line-through; } @media screen and (max-width: 900px) { div#todolist { margin: 1rem 5px 0; } } @media screen and (max-width: 768px) { .list_item{ width: 100%; } } </style> <div id="todolist"></div> <script> // 瀑布流函数,不用管 function waterfall(t){function e(t,e){var n=window.getComputedStyle(e);return parseFloat(n["margin"+t])||0}function n(t){return t+"px"}function r(t){return parseFloat(t.style.left)}function o(t){return t.clientWidth}function l(t){return function(t){return parseFloat(t.style.top)}(t)+function(t){return t.clientHeight}(t)+e("Bottom",t)}function i(t){return r(t)+o(t)+e("Right",t)}function u(t){t=t.sort((function(t,e){return l(t)===l(e)?r(e)-r(t):l(e)-l(t)}))}function a(e){o(t)!=h&&(e.target.removeEventListener(e.type,arguments.callee),waterfall(t))}"string"==typeof t&&(t=document.querySelector(t));var s=[].map.call(t.children,(function(t){return t.style.position="absolute",t}));t.style.position="relative";var f=[];s.length&&(s[0].style.top="0px",s[0].style.left=n(e("Left",s[0])),f.push(s[0]));for(var p=1;p<s.length;p++){var c=s[p-1],y=s[p];if(!(i(c)+o(y)<=o(t)))break;y.style.top=c.style.top,y.style.left=n(i(c)+e("Left",y)),f.push(y)}for(;p<s.length;p++){u(f);y=s[p];var d=f.pop();y.style.top=n(l(d)+e("Top",y)),y.style.left=n(r(d)),f.push(y)}u(f);var v=f[0];t.style.height=n(l(v));var h=o(t);window.addEventListener?window.addEventListener("resize",a):document.body.onresize=a} // 清单函数 todolist(); function todolist() { fetch('https://你的memos地址/api/memo?creatorId=用户ID&tag=清单').then(res => res.json()).then(data => { // 注意替换链接和ID // 获取并处理数据 data = data.data let box = document.getElementById('todolist') data.forEach(item => { // 处理数据 let content = item.content, title = content.match(/\[(.*?)\]/g)[0].replace(/\[(.*?)\]/,'$1'); // 去掉多余内容,替换清单内容 content = content.replace(/#.*\s/g, '').replace(/(-\s\[\s\]\s)(.*)/g, `<li><i style="margin-right: 5px;" class="fa-regular fa-circle"></i>$2</li>`).replace(/(-\s\[x\]\s)(.*)/g, `<li class="achieve"><i style="margin-right: 5px;" class="fa-regular fa-circle-check"></i>$2</li>`); // 渲染数据 let div = document.createElement('div'); div.className = 'list_item'; div.innerHTML = `<h3>${title}</h3><ul>${content}</ul>`; box.appendChild(div); }); waterfall('#todolist'); }).catch() } </script><style> /* 页面初始化 */ div#page { background: none; border: 0; padding: 0; } [data-theme=dark] #twikoo .tk-content, #twikoo .tk-content { padding: 0; background: transparent; } .tk-comments-container>.tk-comment, .tk-submit:nth-child(1){ background: var(--card-bg); border: 1px rgba(188, 188, 188, 0.8) solid; box-shadow: 0 5px 10px rgb(189 189 189 / 10%); transition: all .3s ease-in-out; border-radius: 12px; } .tk-comments-container>.tk-comment:hover, .tk-submit:nth-child(1):hover { border-color: #6dc3fd; } .tk-submit { padding: 20px 10px 0; } .tk-comments-container>.tk-comment { padding: 15px; } /* 页面初始化结束 */ div#todolist { display: flex; flex-wrap: wrap; margin-top: 1rem; } .list_item { display: inline-block; width: calc(50% - .4rem); background: #ffe3dd; border-radius: 12px; padding: 10px 1rem 1.2rem; border: 2px dashed #f7a796; --todo-border: 1px solid #f7a796; margin-right: 1rem; margin-bottom: 1rem; } .list_item h3 { margin: 0; border-bottom: var(--todo-border); } .list_item ul { font-size: 17px; padding: 0 !important; margin: 0; } .list_item li{ margin: 0 !important; border-bottom: var(--todo-border); } .list_item li::marker { content: none; } li.achieve { opacity: .8; text-decoration: line-through; } @media screen and (max-width: 900px) { div#todolist { margin: 1rem 5px 0; } } @media screen and (max-width: 768px) { .list_item{ width: 100%; } } </style> <div id="todolist"></div> <script> // 瀑布流函数,不用管 function waterfall(t){function e(t,e){var n=window.getComputedStyle(e);return parseFloat(n["margin"+t])||0}function n(t){return t+"px"}function r(t){return parseFloat(t.style.left)}function o(t){return t.clientWidth}function l(t){return function(t){return parseFloat(t.style.top)}(t)+function(t){return t.clientHeight}(t)+e("Bottom",t)}function i(t){return r(t)+o(t)+e("Right",t)}function u(t){t=t.sort((function(t,e){return l(t)===l(e)?r(e)-r(t):l(e)-l(t)}))}function a(e){o(t)!=h&&(e.target.removeEventListener(e.type,arguments.callee),waterfall(t))}"string"==typeof t&&(t=document.querySelector(t));var s=[].map.call(t.children,(function(t){return t.style.position="absolute",t}));t.style.position="relative";var f=[];s.length&&(s[0].style.top="0px",s[0].style.left=n(e("Left",s[0])),f.push(s[0]));for(var p=1;p<s.length;p++){var c=s[p-1],y=s[p];if(!(i(c)+o(y)<=o(t)))break;y.style.top=c.style.top,y.style.left=n(i(c)+e("Left",y)),f.push(y)}for(;p<s.length;p++){u(f);y=s[p];var d=f.pop();y.style.top=n(l(d)+e("Top",y)),y.style.left=n(r(d)),f.push(y)}u(f);var v=f[0];t.style.height=n(l(v));var h=o(t);window.addEventListener?window.addEventListener("resize",a):document.body.onresize=a} // 清单函数 todolist(); function todolist() { fetch('https://你的memos地址/api/memo?creatorId=用户ID&tag=清单').then(res => res.json()).then(data => { // 注意替换链接和ID // 获取并处理数据 data = data.data let box = document.getElementById('todolist') data.forEach(item => { // 处理数据 let content = item.content, title = content.match(/\[(.*?)\]/g)[0].replace(/\[(.*?)\]/,'$1'); // 去掉多余内容,替换清单内容 content = content.replace(/#.*\s/g, '').replace(/(-\s\[\s\]\s)(.*)/g, `<li><i style="margin-right: 5px;" class="fa-regular fa-circle"></i>$2</li>`).replace(/(-\s\[x\]\s)(.*)/g, `<li class="achieve"><i style="margin-right: 5px;" class="fa-regular fa-circle-check"></i>$2</li>`); // 渲染数据 let div = document.createElement('div'); div.className = 'list_item'; div.innerHTML = `<h3>${title}</h3><ul>${content}</ul>`; box.appendChild(div); }); waterfall('#todolist'); }).catch() } </script>
使用
使用的格式如下:
#清单 [想去的地方]- [ ] 轻笑的米奇妙妙屋(轻笑让我加的)- [x] 已完成的清单#清单 [想去的地方] - [ ] 轻笑的米奇妙妙屋(轻笑让我加的) - [x] 已完成的清单#清单 [想去的地方] - [ ] 轻笑的米奇妙妙屋(轻笑让我加的) - [x] 已完成的清单
注意,前面的#清单
是固定的。标题用中括号包起来。已完成的将括号内的空格改成x即可。
![图片[7]-memos 使用指南:自建一个备忘录中心服务-大海博客](https://www.dhme.cn/wp-content/uploads/2023/05/c15e07651f023331.webp)
使用心得
#tag 后面必须有个空格才能创建 tag
文章推荐:
- 使用 iOS 快捷指令录入笔记:https://github.com/usememos/memos/discussions/52
- 开源 Memos 在群晖上部署:https://life97.top/synology-memos.html
暂无评论内容