[js] 替换原始 复制为副本 快捷键效果

效果

原来使用 复制副本的快捷键 的效果如下

image.png

image.png

修改后使用 复制副本的快捷键 的效果如下

image.png

image.png

操作

将光标放在需要复制的块里面, 不需要选中, 使用 ctrl+D, 就可以复制

重要

  1. 这个脚本需要 复制为副本的 快捷键, 如果你没有, 请在设置里面添加
  2. 我的 复制为副本的 快捷键是 ctrl+D, 如果你的不是, 请自行修改代码
    if (event.ctrlKey && !event.shiftKey && !event.altKey && event.key === 'd') {
  3. 脚本只会在不选中内容的时候生效: 选中了内容/块 或者 是 图片/代码块, 会使用默认功能

js 代码

(()=>{
// 延迟执行
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
function press_once(keyInit) {
    keyInit["bubbles"] = true;
    let keydownEvent = new KeyboardEvent('keydown', keyInit);
    document.querySelector('[data-type="wnd"].layout__wnd--active .protyle:not(.fn__none) .protyle-wysiwyg.protyle-wysiwyg--attr')?.dispatchEvent(keydownEvent);
    let keyUpEvent = new KeyboardEvent('keyup', keyInit);
    document.querySelector('[data-type="wnd"].layout__wnd--active .protyle:not(.fn__none) .protyle-wysiwyg.protyle-wysiwyg--attr')?.dispatchEvent(keyUpEvent);
}
function press_enter() {
    press_once({
        key: 'Enter',
        keyCode: 13, // 不推荐使用,但某些情况下需要
    });
}
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; // 如果没有选中内容或光标位置无效
}
// 判断孩子节点是不是图片
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 isImgEle() {
    return hasImageChild(getElementAtCursor())
}
function isSelectedDfs(ele) {
    if (ele.classList.contains('protyle-wysiwyg')) {
        return false
    }
    if (ele.classList.contains('protyle-wysiwyg--select')) {
        return true
    }
    return isSelectedDfs(ele.parentElement)
}
function isSelected() {
    let ele = getElementAtCursor()
    return isSelectedDfs(ele)
}
function isCodeBlockDfs(ele) {
    if (ele.classList.contains('protyle-wysiwyg')) {
        return false
    }
    if (ele.classList.contains('hljs')) {
        return true
    }
    return isCodeBlockDfs(ele.parentElement)
}
function isCodeBlock() {
    let ele = getElementAtCursor()
    return isCodeBlockDfs(ele)
}
// 获取当前选中的文本
async function get_selected_data() {
    // 触发 ctrl+c, 复制选中的块
    document.execCommand('copy');
    // 获取剪贴板文本
    return await navigator.clipboard.readText();
}
// 设置文本
async function paste_data(data=null) {
    if (data != null) {
        // 将处理后的文本复制到剪贴板
        await navigator.clipboard.writeText(data);
    }
    // 触发 ctrl+v, 粘贴处理后的内容
    document.execCommand('paste');
    await sleep(20)
}

// 事件监听
document.addEventListener('keydown', async (event) => {
    // 检查是否按下了 Ctrl + d
    if (event.ctrlKey && !event.shiftKey && !event.altKey && event.key === 'd') {
        // event.preventDefault(); // 防止快捷键默认行为
        if (hasSelectedText()) {
            console.log("有选中的文本, 使用默认功能")
            return;
        }
        if (isImgEle()) {
            console.log("选中了图片, 使用默认功能")
            return;
        }
        if (isSelected()) {
            console.log("选中了块, 使用默认功能")
            return;
        }
        if (isCodeBlock()) {
            console.log("是代码块, 使用默认功能")
            return;
        }
  
        event.stopPropagation();  // 停止事件传播
        let data = await get_selected_data();
        console.log(data)
        press_enter()
        press_enter()
        paste_data()
    }
});
})()

  • 思源笔记

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

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

    22362 引用 • 89486 回帖 • 1 关注
  • 代码片段

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

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

    70 引用 • 375 回帖 • 1 关注

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
EmberSky
如果感觉我的回答对你有帮助, 请点击 感谢 支持一下, 谢谢! 杭州