[js] 复制行级代码或图片时, 替换原始复制

操作&效果

默认复制行级代码

操作

  1. 光标放在行级代码中, 不需要选取文本
    image.png
  2. ctrl+c 复制
  3. 复制的内容就是行级代码的原始文本 image.png

其他场景都是默认的效果

  1. 选取部分文本
    image.png
  2. ctrl+c 复制
  3. 复制的内容就是默认的效果: 我这里是 image.png

默认复制原始图片

操作

  1. 选中图片
  2. ctrl+c 复制
  3. 复制的内容就是原始图片
  4. 相当于下面这个操作
    image.png

重要, 重要, 重要!!!

复制图片这个功能需要有复制块引用的快捷键, 我的快捷键是 shift+alt+c

image.png

如果你没有快捷键需要自行增加, 如果你的快捷键不是这个, 需要自行修改这部分代码

image.png

痛点

原本复制的是一个块链接文本, 类似于这样: ![image](assets/image-20241017134127-t1qqjbq.png)

但是我一般复制图片的时候, 都是从笔记里找到图片然后复制到其他地方, 那复制的就不能是链接, 应该是原始图片

重要备注

改之前, ctrl+c 默认复制的都是原始图片

这会导致一个问题, 原来在思源里复制粘贴一个图片, 这两个图片实际上都是块链接, 指向的是同一个文件, 磁盘只占用一个文件的大小

改之后, 相同的操作, 实际上是两份文件, 这两个图片是相同的, 有点浪费, 不过我笔记里一般不会有两个相同的图片, 所以可以接受这个效果

如果想达到之前的效果, 操作就比较复杂, 介意慎用, 自行注释掉: handle_cp_img

js 代码

(()=>{ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 判断是否选取了文本 function hasSelectedText() { const selection = window.getSelection(); return selection && selection.toString().length > 0; } // 获取光标所在的元素 function getElementAtCursor() { const selection = window.getSelection(); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); const startContainer = range.startContainer; // 如果是文本节点,获取其父元素 const element = startContainer.nodeType === 3 ? startContainer.parentNode : startContainer; return element; } return null; // 如果没有选中内容或光标位置无效 } // 处理复制行级代码 async function handle_cp_line_code(element) { if (!element) { return; } if (element.getAttribute('data-type') === 'code' && !hasSelectedText()) { // 如果是代码块,并且没有选中内容, 则复制代码块内容 let content = element.textContent; if (content.startsWith('\u200B')) { content = content.slice(1); // 移除前面的零宽空格 } await navigator.clipboard.writeText(content); await sleep(20) } } // 判断孩子节点是不是图片 function hasImageChild(element) { if (!element) { return false; } // 获取该元素的所有孩子节点 const children = element.children; for (let i = 0; i < children.length; i++) { // 检查孩子节点的 data-type 属性 if (children[i].getAttribute('data-type') === 'img') { return true; // 找到符合条件的孩子节点 } } return false; // 没有符合条件的孩子节点 } // 处理复制图片 function handle_cp_img(element) { if (!element) { return; } if (hasImageChild(element)) { let keyInit = { ctrlKey: false, altKey: true, shiftKey: true, key: 'C', keyCode: 67, // 不推荐使用,但某些情况下需要 bubbles: true, } let keydownEvent = new KeyboardEvent('keydown', keyInit); element.dispatchEvent(keydownEvent); let keyUpEvent = new KeyboardEvent('keyup', keyInit); element.dispatchEvent(keyUpEvent); } } // 事件监听 document.addEventListener('keydown', async (event) => { if (event.ctrlKey && !event.shiftKey && !event.altKey && event.key === 'c') { // event.preventDefault(); // 防止快捷键默认行为 let element = getElementAtCursor(); // 判断是否需要复制行级代码, 并复制 handle_cp_line_code(element); // 判断是否是图片, 并复制图片 handle_cp_img(element); } }); })()
  • 思源笔记

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

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

    25120 引用 • 103566 回帖 • 1 关注
  • 代码片段

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

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

    142 引用 • 954 回帖 • 2 关注
1 操作
EmberSky 在 2024-11-08 14:52:25 更新了该帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • MaxYang via macOS

    感谢,提醒大家一下,如果用的 mac 代码里面的 event.ctrlKey 需要改成 event.metaKey

  • EmberSky 1 评论

    复制行级代码时有 bug, 前缀会多一个空白字符

    需要将 handle_cp_line_code 函数修改成下面这个

    // 处理复制行级代码 async function handle_cp_line_code(element) { if (!element) { return; } if (element.getAttribute('data-type') === 'code' && !hasSelectedText()) { // 如果是代码块,并且没有选中内容, 则复制代码块内容 let content = element.textContent; if (content.startsWith('\u200B')) { content = content.slice(1); // 移除前面的零宽空格 } await navigator.clipboard.writeText(content); await sleep(20) } }
    1 回复
    已更新到帖子的代码上
    EmberSky
  • 感谢大佬的代码片段,非常好用

  • 直接在原文上改吧,这个零宽空格在文本中显示不出来,等我放在命令行中运行的时候才发现多了一个空格,怪不得一直报错 😂

  • [bug]无法批量复制图片

    视频效果:

    1 回复
  • EmberSky

    你这两个是图片么, 我这里是正常的, 可以同时复制两个

请输入回帖内容 ...