[js] 添加一个顶栏按钮,实现点击即打开代码片段界面

本贴最后更新于 283 天前,其中的信息可能已经时移世异

最终实现的 JS 代码片段:

/** * 在顶栏添加按钮,快捷打开代码片段界面 JS片段 * 参考 https://ld246.com/article/1674026309504 修改,同时感谢 [Undii](https://ld246.com/member/Undii) 提供 帮助 * 为顶栏增加代码片段按钮,点击后创建快捷键按下事件 * 挂件模式支持点击日记列出笔记本。 https://ld246.com/article/1674026309504 */ // 设置是否添加对应按钮 let g_addSnippets = true;// 设置 // 插入按钮 // 插入日历笔记本选择挂件 // 参考: https://ld246.com/article/1662969146166 原作者: BryceAndJuly // 参考: https://github.com/svchord/Rem-Craft 原作者: Seven Chor function addSnippets() { let barMode = document.getElementById("barMode"); barMode.insertAdjacentHTML( "afterend", '<div id="barSnippets_simulate" class="toolbar__item ariaLabel" aria-label="代码片段/Snippets"></div>' ); let settingBtn = document.getElementById("barSnippets_simulate"); settingBtn.innerHTML = `<svg><use xlink:href="#iconCode"></use></svg>`; settingBtn.addEventListener( "click", function (e) { dispatchKeyEvent("config"); setTimeout(function() { // 找到包含 data-name="appearance" 的 <li> 元素 var element = document.querySelector('li[data-name="appearance"]'); // 创建一个点击事件 var event = new MouseEvent('click', { bubbles: true, cancelable: true, view: window }); // 触发点击事件 element.dispatchEvent(event); }, 100); // 1000毫秒 = 1秒 setTimeout(function() { // 获取按钮元素 var button = document.getElementById('codeSnippet'); // 创建一个新的点击事件 var clickEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); // 触发按钮的点击事件 button.dispatchEvent(clickEvent); }, 200); // 1000毫秒 = 1秒 } ); } /** * */ function dispatchKeyEvent(functionName) { let keyInit = parseHotKeyStr(window.top.siyuan.config.keymap.general[functionName].custom); keyInit["bubbles"] = true; let keydownEvent = new KeyboardEvent('keydown', keyInit); document.getElementsByTagName("body")[0].dispatchEvent(keydownEvent); let keyUpEvent = new KeyboardEvent('keyup', keyInit); document.getElementsByTagName("body")[0].dispatchEvent(keyUpEvent); } /** * * @param {*} hotkeyStr 思源hotkey格式 Refer: https://github.com/siyuan-note/siyuan/blob/d0f011b1a5b12e5546421f8bd442606bf0b5ad86/app/src/protyle/util/hotKey.ts#L4 * @returns KeyboardEventInit Refer: https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/KeyboardEvent */ function parseHotKeyStr(hotkeyStr) { let result = { ctrlKey: false, altKey: false, metaKey: false, shiftKey: false, key: 'A', keyCode: 0 } if (hotkeyStr == "" || hotkeyStr == undefined || hotkeyStr == null) { console.error("解析快捷键设置失败", hotkeyStr); throw new Error("解析快捷键设置失败"); } let onlyKey = hotkeyStr; if (hotkeyStr.indexOf("⌘") != -1) { result.ctrlKey = true; onlyKey = onlyKey.replace("⌘", ""); } if (hotkeyStr.indexOf("⌥") != -1) { result.altKey = true; onlyKey = onlyKey.replace("⌥", ""); } if (hotkeyStr.indexOf("⇧") != -1) { result.shiftKey = true; onlyKey = onlyKey.replace("⇧", ""); } // 未处理 windows btn (MetaKey) result.key = onlyKey; // 在https://github.com/siyuan-note/siyuan/commit/70acd57c4b4701b973a8ca93fadf6c003b24c789#diff-558f9f531a326d2fd53151e3fc250ac4bd545452ba782b0c7c18765a37a4e2cc // 更改中,思源改为使用keyCode判断快捷键按下事件,这里进行了对应的转换 // 另请参考该提交中涉及的文件 result.keyCode = keyCodeList[result.key]; console.assert(result.keyCode != undefined, `keyCode转换错误,key为${result.key}`); switch (result.key) { case "→": { result.key = "ArrowRight"; break; } case "←": { result.key = "ArrowLeft"; break; } case "↑": { result.key = "ArrowUp"; break; } case "↓": { result.key = "ArrowDown"; break; } case "⌦": { result.key = "Delete"; break; } case "⌫": { result.key = "Backspace"; break; } case "↩": { result.key = "Enter"; break; } } return result; } if (g_addSnippets) addSnippets(); const keyCodeList = { "⌫": 8, "⇥": 9, "↩": 13, "⇧": 16, "⌘": 91, "⌥": 18, "Pause": 19, "CapsLock": 20, "Escape": 27, " ": 32, "PageUp": 33, "PageDown": 34, "End": 35, "Home": 36, "←": 37, "↑": 38, "→": 39, "↓": 40, "PrintScreen": 44, "Insert": 45, "⌦": 46, "0": 48, "1": 49, "2": 50, "3": 51, "4": 52, "5": 53, "6": 54, "7": 55, "8": 56, "9": 57, "A": 65, "B": 66, "C": 67, "D": 68, "E": 69, "F": 70, "G": 71, "H": 72, "I": 73, "J": 74, "K": 75, "L": 76, "M": 77, "N": 78, "O": 79, "P": 80, "Q": 81, "R": 82, "S": 83, "T": 84, "U": 85, "V": 86, "W": 87, "X": 88, "Y": 89, "Z": 90, "ContextMenu": 93, "MyComputer": 182, "MyCalculator": 183, ";": 186, "=": 187, ",": 188, "-": 189, ".": 190, "/": 191, "`": 192, "[": 219, "\\": 220, "]": 221, "'": 222, "*": 106, "+": 107, "-": 109, ".": 110, "/": 111, "F1": 112, "F2": 113, "F3": 114, "F4": 115, "F5": 116, "F6": 117, "F7": 118, "F8": 119, "F9": 120, "F10": 121, "F11": 122, "F12": 123, "NumLock": 144, "ScrollLock": 145 };

原贴:

看到个 帖子 ,添加按钮应该是这样:

function addSnippets() { let barMode = document.getElementById("barMode"); barMode.insertAdjacentHTML( "afterend", '<div id="barSnippets_simulate" class="toolbar__item ariaLabel" aria-label="代码片段/Snippets" ></div>' ); let settingBtn = document.getElementById("barSnippets_simulate"); settingBtn.innerHTML = `<svg><use xlink:href="#iconCode"></use></svg>`; settingBtn.addEventListener("click", function() { openSnippets(); }, false); } function openSnippets() { } addSnippets();

但是我不知道怎么打开代码片段界面

  • 思源笔记

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

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

    26361 引用 • 109622 回帖 • 1 关注
  • 代码片段

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

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

    203 引用 • 1474 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    10141 引用 • 46076 回帖 • 63 关注
1 操作
JeffreyChen 在 2024-10-04 17:26:37 更新了该帖

相关帖子

被采纳的回答
  • Undii 1 via Android

    主要是 模拟点击应该在 点击顶栏按钮、并且打开设置页之后进行
    你这里的 setTimeout 并没有和点击顶栏按钮关联起来,也就是,“延迟模拟点击打开代码片段”,这个事情之会在代码生效时执行一次。在 4 秒内打开了设置,这里代码就会正确执行一次。

    settingBtn.addEventListener( "click", function (e) { dispatchKeyEvent("config"); // setTimeout写在这里 } );

    上面的代码,是将 click 点击顶栏按钮的事件和 function 关联了起来,具体的,这里执行了 dispatchKeyEvent 来模拟快捷键打开设置页面,

    所以 setTimeout 应该写在这里;

    我也在原帖中更新了相应的代码。

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • niop

    假如你只想通过代码片段来实现,可以用代码模拟点击 siyuan-> 设置-> 外观-> 代码片段来实现.

    也可以用 openapi 实现. fetchPost /api/snippet/getSnippet", 具体代码可参考 siyuan\app\src\config\util\snippets.ts

    1 回复
  • 其他回帖
  • 我首先理解了基础代码,然后再修改到可以正常打开设置界面,之后模拟点击我不会,就用开发者工具找到那个元素,然后:

    我:怎么用 JS 模拟点击按钮:<button class="b3-button b3-button--outline fn__flex-center fn__size200" id="codeSnippet"><svg><use xlink:href="#iconSettings"></use></svg>设置 </button>

    GPT:要使用 JavaScript 模拟点击按钮,可以通过以下步骤实现:

    1. 首先,获取对应的按钮元素。在这种情况下,您可以使用按钮的 id 属性来获取该元素。
    var button = document.getElementById('codeSnippet');
    1. 然后,您可以使用 click() 方法来模拟点击按钮。
    button.click();

    整体代码如下:

    var button = document.getElementById('codeSnippet'); button.click();

    这样,当您运行这段 JavaScript 代码时,它将模拟点击具有 id 为 codeSnippet 的按钮。

    我:让这个模拟点击在这段程序的最后阶段执行:

    function addSnippets() { let barMode = document.getElementById("barMode"); barMode.insertAdjacentHTML( "afterend", '<div id="barSnippets_simulate" class="toolbar__item ariaLabel" aria-label="代码片段/Snippets" ></div>' ); let settingBtn = document.getElementById("barSnippets_simulate"); settingBtn.innerHTML = `<svg><use xlink:href="#iconCode"></use></svg>`; settingBtn.addEventListener( "click", function (e) { dispatchKeyEvent("config"); }, false ); }

    GPT:要在这段程序的最后阶段执行模拟点击按钮的操作,您可以在 addSnippets() 函数的最后调用前面提到的模拟点击按钮的代码。这样可以确保在设置按钮被添加到页面并且事件监听器被设置后再触发点击事件。

    下面是修改后的代码:

    function addSnippets() { let barMode = document.getElementById("barMode"); barMode.insertAdjacentHTML( "afterend", '<div id="barSnippets_simulate" class="toolbar__item ariaLabel" aria-label="代码片段/Snippets" ></div>' ); let settingBtn = document.getElementById("barSnippets_simulate"); settingBtn.innerHTML = `<svg><use xlink:href="#iconCode"></use></svg>`; settingBtn.addEventListener( "click", function (e) { dispatchKeyEvent("config"); }, false ); // 模拟点击按钮 var button = document.getElementById('codeSnippet'); button.click(); }

    在这个修改后的代码中,addSnippets() 函数会先执行添加设置按钮的操作,然后再执行模拟点击按钮的操作。这样可以确保在设置按钮被添加到页面并且事件监听器被设置后再触发点击事件。

    然后发现界面加载要一点时间,于是就:

    我:我想在前面增加 1s 的延时

    GPT:要在调用按钮点击事件处理程序之前增加 1 秒的延时,您可以使用 setTimeout() 函数来实现。setTimeout() 函数可以在指定的时间间隔后执行指定的函数。

    下面是一个示例代码,演示如何在调用按钮点击事件处理程序之前增加 1 秒的延时:

    // 获取按钮元素 var button = document.getElementById('codeSnippet'); // 创建一个新的点击事件 var clickEvent = new MouseEvent('click', { view: window, bubbles: true, cancelable: true }); // 增加1秒延时后触发按钮的点击事件 setTimeout(function() { button.dispatchEvent(clickEvent); }, 1000); // 1000毫秒 = 1秒

    在这段代码中,setTimeout() 函数会在 1 秒后触发指定的函数,该函数会触发按钮的点击事件处理程序。这样就实现了在调用按钮点击事件处理程序之前增加 1 秒的延时。

    我就自己把代码加上去了。

  • Undii 1 1 评论 via Android

    主要是 模拟点击应该在 点击顶栏按钮、并且打开设置页之后进行
    你这里的 setTimeout 并没有和点击顶栏按钮关联起来,也就是,“延迟模拟点击打开代码片段”,这个事情之会在代码生效时执行一次。在 4 秒内打开了设置,这里代码就会正确执行一次。

    settingBtn.addEventListener( "click", function (e) { dispatchKeyEvent("config"); // setTimeout写在这里 } );

    上面的代码,是将 click 点击顶栏按钮的事件和 function 关联了起来,具体的,这里执行了 dispatchKeyEvent 来模拟快捷键打开设置页面,

    所以 setTimeout 应该写在这里;

    我也在原帖中更新了相应的代码。

    1 回复
    用 api 的话 返回的是代码片段的内容 需要自己写一个 dialog 显示 这个最好用插件做。
    Undii
  • kikkawa via macOS

    很实用,谢谢

  • 查看全部回帖
JeffreyChen
思源笔记同步教程:https://ld246.com/article/1692089679062 爱发电:https://afdian.com/a/JeffreyChen

推荐标签 标签

  • React

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

    192 引用 • 291 回帖 • 369 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 185 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 143 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 53 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 85 关注
  • 电影

    这是一个不能说的秘密。

    123 引用 • 608 回帖
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    374 引用 • 1859 回帖 • 1 关注
  • Excel
    31 引用 • 28 回帖
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 395 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 1 关注
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 662 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 826 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 2 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 108 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    10 引用 • 15 回帖
  • Dubbo

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

    60 引用 • 82 回帖 • 617 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 62 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 44 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 2 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    93 引用 • 122 回帖 • 616 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 545 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 611 关注
  • Jenkins

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

    54 引用 • 37 回帖 • 1 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    955 引用 • 944 回帖
  • RabbitMQ

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

    49 引用 • 60 回帖 • 353 关注
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 713 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 522 关注