-
无需打开链滴,新帖及新消息提示 3 方案
2025-08-24 20:03 -
分享一个牛逼的网站
2025-08-21 11:01好想法,但还是需要注册登录一下,没这个方便,这个缺点就是国内网络不稳定。
期望国内能有类似版本。
也可以自己搭建,类似源码挺多的,核心就是利用 WebRTC 那套东西实现的。
而且国内外各大云厂商已经封装了这些基础实现,只需要实现上层应用即可。
或者用腾讯会议的直播功能也不错,可以在线 web 观看。
-
求助日记记录方式
2025-08-20 12:18只需要在你的笔记上右键-> 设置,设置新建日记存放路径即可


日记存放路径文字版
/daily note/{{now | date "2006"}}/{{now | date "2006"}}W{{now | ISOWeek}}这样,当你按 alt+5 时如果记不存在时会新建,已存在则直接打开
最终效果如下

注意:以上仅供参考,实际路径根据你自己的需要进行调整
-
求助大佬帮完善个 js,在移动端页面上侧工具栏再添加一个按钮,实现复制块超链接功能
2025-08-19 17:04 -
求助大佬帮完善个 js,在移动端页面上侧工具栏再添加一个按钮,实现复制块超链接功能
2025-08-19 15:52我意思是把这段代码追加到上面的代码里。
然后你需要复制的地方调用 await copyPlainText(`siyuan://blocks/20250807172700-e1jsytg`);
-
求助大佬帮完善个 js,在移动端页面上侧工具栏再添加一个按钮,实现复制块超链接功能
2025-08-19 15:37你不都实现了吗?无非多加一个复制到剪切板而已,把 openBlock()换成 copyPlainText()即可。
要想兼容性好,可以使用下面的代码
async function copyPlainText (text) { text = text.replace(new RegExp("\u200b", "g"), ""); // `复制纯文本` 时移除所有零宽空格 https://github.com/siyuan-note/siyuan/issues/6674 await writeText(text); } // see https://github.com/siyuan-note/siyuan/blob/5f0f4e3ba6aabd5af26f9879695e5b9b796b5fb9/app/src/protyle/util/compatibility.ts#L129C14-L129C24 function writeText(text) { let range; if (getSelection().rangeCount > 0) { range = getSelection().getRangeAt(0).cloneRange(); } try { // navigator.clipboard.writeText 抛出异常不进入 catch,这里需要先处理移动端复制 if (isInAndroid()) { window.JSAndroid.writeClipboard(text); return; } if (isInHarmony()) { window.JSHarmony.writeClipboard(text); return; } if (isInIOS()) { window.webkit.messageHandlers.setClipboard.postMessage(text); return; } navigator.clipboard.writeText(text); } catch (e) { if (isInIOS()) { window.webkit.messageHandlers.setClipboard.postMessage(text); } else if (isInAndroid()) { window.JSAndroid.writeClipboard(text); } else if (isInHarmony()) { window.JSHarmony.writeClipboard(text); } else { const textElement = document.createElement("textarea"); textElement.value = text; textElement.style.position = "fixed"; //avoid scrolling to bottom document.body.appendChild(textElement); textElement.focus(); textElement.select(); document.execCommand("copy"); document.body.removeChild(textElement); if (range) { focusByRange(range); } } } function isInAndroid() { return window.siyuan.config.system.container === "android" && window.JSAndroid; } function isInIOS() { return window.siyuan.config.system.container === "ios" && window.webkit?.messageHandlers; } function isInHarmony() { return window.siyuan.config.system.container === "harmony" && window.JSHarmony; } }调用方式,比如复制块超级链接
await copyPlainText(`siyuan://blocks/20250807172700-e1jsytg`);
复制为 Markdown 链接
await copyPlainText(`[你的块内容](siyuan://blocks/20250807172700-e1jsytg)`);
-
为什么 gemini 的内容复制进 siyuan,会出现格式问题
2025-08-19 12:02有没有可能是 gemini 的问题,而不是思源的问题?
比如,gemini 复制后的代码换行挤到一块了,思源无法识别。
如图

修改后的代码再粘贴到思源没问题。
不过,应该可以改进吧 @88250
用 js 把
$$后增加换行应该可以。 -
求助代码片段
2025-08-18 19:21css 无法识别是否白色背景,js 虽然能识别,但图片多了影响性能。
建议人工标注,比如,给图片提示文本加上 white-bg 前缀

然后可以用 css 这样
[data-theme-mode="dark"] img[alt^="white-bg"]{ filter: invert(1) brightness(0.9); }当然,也可以封装成 js,比如右键“反转”,但人工标注少不了。
-
[js] 求 JS 任务列表自动勾选 / 取消父任务
2025-08-18 00:45正如楼上 @Fighter93 大佬所说,这两个新增需求,让复杂度陡然上升。
列表结构本身就复杂,再加上动态增加,删除,粘贴,移动等操作,让复杂度陡增。
以下代码基于规律的实现,进行了简单测试,复杂时可能会有 bug。
请根据自己的使用场景测试无误后使用,由此产生的任何后果,作者不承担任何责任。
0.0.2 版更新内容如下:
新增需求:
- 当一个已完成的父任务新增一个子任务时,由于新子任务默认是未完成(未勾选),所以父任务应自动取消勾选。
- 当父任务下只剩一个未完成子任务时,若删除该子任务,则父任务应自动变为已完成(勾选)。
代码已在之前的帖子中更新。
还有一种实现方式,暴力法,即只要任务结点发生变化,均扫描一遍任务项进行判断,但这种方法,也有缺陷,即当用户手动取消勾选后,当别的任务修改时,可能会根据规律又自动勾选。由于这种方式实现简单,可借助 ai 实现,我测试时,已分别用 deepseek 和 chatgpt 成功实现,如需要这种的,请自行咨询 ai。
-
能使用 js 代码实现查找未引用的资源文件吗?
2025-08-17 20:27因为你文档中的路径和文件夹中的路径不一样,如图所示

看个人需求,如果你想不区分大小写,我改下代码,如果想区分就不用改了
-
能使用 js 代码实现查找未引用的资源文件吗?
2025-08-17 14:15原本存在 assets/assets buck/文件夹内的图片丢失后不会出现按钮,复现成功。还有之前我使用了大佬你给的导出未引用的资源文件.js,这会使用现在这个 js 代码不能查找导出的资源文件吗?导出资源文件夹我是放在 assets 文件夹内的
嗯,确实之前用的官方 api searchAsset 这个 api 有缺陷,不能查找自定义文件夹中的文件。
看来只能自己实现了,稍后我重写下这个查找。
-
能使用 js 代码实现查找未引用的资源文件吗?
2025-08-17 13:44不显示 按钮问题 已经修复了,更新到 0.0.4 即可
你说之前的图片失败是怎么回事?就那一个图片问题,还是之前的所有图片都失败?能否稳定重现?
之前的图片路径是什么?文章中的图片路径又是什么?
如果方便的话,可以上传论坛一个测试文档 zip 看看。
-
能使用 js 代码实现查找未引用的资源文件吗?
2025-08-16 17:11 -
[js] 求 JS 任务列表自动勾选 / 取消父任务
2025-08-16 06:22试试这个

/* // 自动勾选取消父任务 see https://ld246.com/article/1755052956165 version 0.0.2 0.0.2 增加新需求 需求: 一个任务列表中有多个子任务, 当子任务全部勾选后, 父任务自动勾选, 当子任务有一个取消勾选后, 父任务也自动取消勾选 支持多层级任务列表, 比如,当三级任务列表都勾选后, 二级任务列表自动勾选, 当此二级任务列表为最后一个未勾选的, 那么这第一级任务列表也自动勾选 新增需求: 1. 当一个已完成的父任务新增一个子任务时,由于新子任务默认是未完成(未勾选),所以父任务应自动取消勾选。 2. 当父任务下只剩一个未完成子任务时,若删除该子任务,则父任务应自动变为已完成(勾选)。 */ setTimeout(() => { const container = document.querySelector('.layout__center, #editor'); if (!container) return; container.addEventListener('click', async (e) => { if (e.altKey || e.shiftKey || e.ctrlKey || e.metaKey || !e.target.closest('.protyle-action--task')) return; await new Promise(resolve => setTimeout(resolve, 50)); // 获取祖先元素并模拟点击 const item = e.target.closest('[data-subtype="t"][data-type="NodeListItem"]'); clickParentItems(item); }, true); // 观察 container 的子树变化(基于规律的处理,可能有bug) const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { // 处理新增的子任务 for (const node of mutation.addedNodes) { if (node.nodeType !== 1) continue; if (node.matches('div[data-type="NodeListItem"][data-subtype="t"]')) { clickParentItems(node); } else if (node.matches('div[data-type="NodeList"][data-subtype="t"]')) { const items = node.querySelectorAll('div[data-type="NodeListItem"][data-subtype="t"]'); items.forEach(item => clickParentItems(item)); } else { const items = node.querySelectorAll('div[data-type="NodeListItem"][data-subtype="t"]'); if (items.length) items.forEach(item => clickParentItems(item)); } } // 处理删除的子任务 for (const node of mutation.removedNodes) { if (node.nodeType !== 1) continue; if (node.matches('div[data-type="NodeListItem"][data-subtype="t"]')) { clickParentItems(mutation.target.querySelector('div[data-type="NodeListItem"][data-subtype="t"]')); } } } }); observer.observe(container, { childList: true, subtree: true, attributes: false }); function clickParentItems(item) { const parentItems = getParentsItems(item); if (parentItems.length === 0) return; for (const item of parentItems) { const list = item?.closest('[data-type="NodeList"][data-subtype="t"]'); const hasUnDone = list?.querySelector(':scope > [data-subtype="t"][data-type="NodeListItem"] > .protyle-action--task use[*|href="#iconUncheck"]'); const parentItem = item.parentElement?.closest('[data-type="NodeListItem"][data-subtype="t"]'); const parentTaskCheck = parentItem?.querySelector('.protyle-action--task'); const parentIsChecked = parentTaskCheck?.querySelector('use[*|href="#iconUncheck"]') ? false : true; // 当存在不可勾选的任务项目时,终止,不再向上级遍历,如果你想继续遍历可把此处的return改为continue if (!parentTaskCheck) return; if (hasUnDone) { // 当有未完成的子任务时,如果父任务已勾选需求要取消 if (parentIsChecked) parentTaskCheck.click(); } else { // 当全部勾选了子任务时,如果父任务未勾选则勾选 if (!parentIsChecked) parentTaskCheck.click(); } } } // 获取祖先任务项 function getParentsItems(item, includeSelf = true) { if (!item) return []; const items = []; // 是否包含自己 if (includeSelf) { items.push(item); } // 向上遍历所有符合条件的祖先 NodeListItem let current = item; while (true) { const parentItem = current.parentElement?.closest('[data-subtype="t"][data-type="NodeListItem"]'); if (!parentItem) break; items.push(parentItem); current = parentItem; } return items; } }, 2000);
题外话:
今天发生了一件奇怪的事,我写代码时看了下时间 6:08,写完,又看了下时间还是 6:08,秒没注意。
难道刚刚时间静止了?之前也出现过这种错觉。
好吧,如果以后写代码时都能时间静止就好了,就可以无敌了

后人有诗叹曰
:屏光冷映键飞忙,
回看时针竟未航。
若得封时锁宙宇,
Deadline 前自徜徉。 -
有什么办法将未引用的资源文件导出吗?
2025-08-15 13:02js 实现

改造于 [js] 清理未引用的数据库
注意:
- 一气呵成,没有发现报错情况,未经严格测试,请自行严格测试无误后使用(建议在新空间测试,以防影响正式数据)
- 请测试关闭笔记本的资源是否会被误删除或受到别的影响
- 本代码仅供学习参考之用,非完善正式产品,请自行决定使用方式,由此造成的任何后果,作者不承担任何责任。
带清除历史版,会写入操作到数据历史中
-
[js] 粘贴为网络图片和本地图片(支持粘贴 gif 保持动画不失效,可拦截思源默认 gif 粘贴)
2025-08-15 11:28嗯,后续看看,可能和 windows 有关,现在没有 windows 系统,无法重现,空了再看。













