[js] 添加斜杠菜单选项 示例

效果

JS 片段

// 添加斜杠菜单选项 示例 JS片段 // 参考 https://ld246.com/article/1746977623250 function getMyPlugin(pluginName = "background-color-1") { let myPlugin = window.siyuan.ws.app.plugins.find(item=>item.name === pluginName); if(myPlugin) return myPlugin; class EventBus { constructor(name = "") { this.eventTarget = document.createComment(name); document.appendChild(this.eventTarget); } on(type, listener) { this.eventTarget.addEventListener(type, listener); } once(type, listener) { this.eventTarget.addEventListener(type, listener, { once: true }); } off(type, listener) { this.eventTarget.removeEventListener(type, listener); } emit(type, detail) { return this.eventTarget.dispatchEvent(new CustomEvent(type, { detail, cancelable: true })); } } class Plugin { constructor(options) { this.app = options.app||window.siyuan.ws.app.appId; this.i18n = options.i18n; this.displayName = options.displayName||options.name; this.name = options.name; this.eventBus = new EventBus(options.name); this.protyleSlash = [{ filter: ["background color 1", "背景色 1", "bjs1"], html: `<div class="b3-list-item__first"><div style="color: var(--b3-theme-on-background); background-color: var(--b3-font-background1);" class="color__square color__square--list">A</div><span class="b3-list-item__text">背景色 1</span></div>`, id: "backgroundColor_1", callback(protyle, nodeElement) { const range = protyle.protyle.toolbar.range; range.deleteContents(); nodeElement.style.backgroundColor = "var(--b3-font-background1)"; nodeElement.style.setProperty("--b3-parent-background", "var(--b3-font-background1)"); const fetchPost = async (url, data) => { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }); return await response.json(); }; fetchPost("/api/attr/setBlockAttrs", { id: nodeElement.getAttribute("data-node-id"), attrs: { style: nodeElement.getAttribute("style") } }); } }]; this.customBlockRenders = {}; this.topBarIcons = []; this.statusBarIcons = []; this.commands = []; this.models = {}; this.docks = {}; this.data = {}; this.protyleOptionsValue = null; } onload() {} onunload() {} uninstall() {} async updateCards(options) { return options; } // 返回选项本身 onLayoutReady() {} addCommand(command) {} addIcons(svg) {} addTopBar(options) { return null; } // 模拟返回null addStatusBar(options) { return null; } // 模拟返回null // 去掉设置,参考 https://github.com/siyuan-note/siyuan/blob/dae6158860cc704e353454565c96e874278c6f47/app/src/plugin/openTopBarMenu.ts#L25 //openSetting() {} loadData(storageName) { return Promise.resolve(null); } saveData(storageName, data) { return Promise.resolve(); } removeData(storageName) { return Promise.resolve(); } getOpenedTab() { return {}; } // 返回空对象 addTab(options) { return () => {}; } // 返回空函数模拟模型 addDock(options) { return {}; } // 返回空对象模拟 dock addFloatLayer(options) {} updateProtyleToolbar(toolbar) { return toolbar; } // 返回toolbar本身 set protyleOptions(options) {} get protyleOptions() { return this.protyleOptionsValue; } } myPlugin = new Plugin({name:pluginName}); window.siyuan.ws.app.plugins.push(myPlugin); return myPlugin; } getMyPlugin();
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    26026 引用 • 108001 回帖 • 1 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    188 引用 • 1322 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 其实,可以这样更优雅,不用每次都用一个新的实例

    getMyPlugin().protyleSlash.push({});

    或者添加一个新增方法

    public addProtyleSlash(slash: {
    filter: string[],
    html: string,
    id: string,
    callback(protyle: Protyle): void,
    })


    之前用纯监听法实现的

    (()=>{ // 调用示例 onSlashChange('hello slash', {icon:'', id:'helloSlash', text:'Hello slash'}, (event, cursorEl)=>{ console.log(cursorEl); return 'Hello slash'; }); function onSlashChange(filterTexts, button, callback) { let lastFilterText = ''; document.addEventListener('input', async (event) => { const cursorEl = getCursorElement(); const cursorText = cursorEl?.textContent; if (cursorText.indexOf('/') !== -1 || cursorText.indexOf('、') !== -1) { const sp = cursorText.indexOf('/') !== -1 ? '/' : '、'; const filterText = cursorText?.split(sp)?.pop()?.trim()?.toLowerCase() || ''; if (filterText === '' || lastFilterText !== filterText) { lastFilterText = filterText; filterTexts = Array.isArray(filterTexts) ? filterTexts.join(" ") : filterTexts; if (!filterText.toLowerCase().trim()||filterText.toLowerCase().split('').some(char=>filterTexts.includes(char))) { const protyle = cursorEl.closest('.protyle'); const hintEl = protyle.querySelector('.protyle-hint'); const icon = button?.icon || `<svg class="b3-list-item__graphic"><use xlink:href="#iconDot"></use></svg>`; const html = `<button data-id="${button.id}" style="width: calc(100% - 16px)" class="b3-list-item b3-list-item--two" data-value="${button?.value||'plugin'}"><div class="b3-list-item__first">${icon}<span class="b3-list-item__text">${button.text}</span></div></button>`; await sleep(40); const hintListEl = hintEl?.firstElementChild; if (!hintListEl) return; if (hintEl.classList.contains('fn__none')) { hintListEl.innerHTML = html; hintListEl.querySelector(`[data-id="${button.id}"]`).classList.add('b3-list-item--focus'); hintEl.classList.remove('fn__none'); } else { if (hintListEl.querySelector(`[data-id="${button.id}"]`)) return; hintListEl.insertAdjacentHTML('beforeend', html); } const inlineEl = hintListEl.querySelector(`[data-id="${button.id}"]`); inlineEl.addEventListener('click', async (event) => { window.requestAnimationFrame(async () => { const result = callback(event, cursorEl); if(!button?.value || button?.value==='plugin') { if(result !== undefined) insertToEditor(result); } }); }, true); } } } }, true); document.addEventListener('keydown', async (event) => { if (event.key !== 'Enter' || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return; if (event.target.closest('.protyle')?.querySelector('.protyle-hint:not(.fn__none) .b3-list-item--focus[data-id="'+button.id+'"]')) { window.requestAnimationFrame(async () => { cursorEl = getCursorElement(); const result = callback(event, cursorEl); if(!button?.value || button?.value==='plugin') { if(result !== undefined) insertToEditor(result); } }); } }, true); } function insertToEditor(text) { document.execCommand('insertHTML', false, text); const inputEvent = new Event('input', { bubbles: true }); document.activeElement.dispatchEvent(inputEvent); } function getCursorElement() { const selection = window.getSelection(); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); // 获取选择范围的起始位置所在的节点 const startContainer = range.startContainer; // 如果起始位置是文本节点,返回其父元素节点 const cursorElement = startContainer.nodeType === Node.TEXT_NODE ? startContainer.parentElement : startContainer; return cursorElement; } return null; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } })();
    1 操作
    wilsons 在 2025-06-17 19:58:21 更新了该回帖
JeffreyChen
思源笔记同步教程:https://ld246.com/article/1692089679062 爱发电:https://afdian.com/a/JeffreyChen

推荐标签 标签

  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 1 关注
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 648 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 2 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 370 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    81 引用 • 409 回帖
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖 • 1 关注
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    63 引用 • 289 回帖
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 5 关注
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 178 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 120 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖 • 1 关注
  • 音乐

    你听到信仰的声音了么?

    62 引用 • 512 回帖
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    42 引用 • 130 回帖 • 252 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 5 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 614 关注
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 1 关注
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 554 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 444 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 77 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1443 引用 • 10082 回帖 • 496 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 597 回帖
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 349 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 1 关注