[js] 快捷键 合并和拆分块 -- 完善版

写在前面

  1. 合并功能, 是对之前那个帖子里面的代码进行优化, 适配了更多场景
  2. 拆分功能是新加的
  3. 个人感觉当前这个比较好用

合并

操作和效果

合并触发键: ctrl+r

合并操作和效果参考这里: [js] 通过快捷键实现简单的合并块 - tenge 的回帖

拆分

操作

拆分触发键: ctrl+q

效果

普通文本

image.png

列表

image.png

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 press_up() {
    press_once({
        key: 'ArrowUp',
        keyCode: 38, // 不推荐使用,但某些情况下需要
    });
}
// 获取光标所在的元素
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 get_selected_data() {
    // 触发 ctrl+c, 复制选中的块
    document.execCommand('copy');
    // 获取剪贴板文本
    return await navigator.clipboard.readText();
}
// 设置文本
async function paste_data(data) {
    // 将处理后的文本复制到剪贴板
    await navigator.clipboard.writeText(data);
    // 触发 ctrl+v, 粘贴处理后的内容
    document.execCommand('paste');
    await sleep(20)
  
}
async function add_new_line() {
    press_enter()
    for(i = 0; i < 10; i++) {
        // 获取当前行内容
        let tmp = await get_selected_data()
        press_enter();
        if (tmp == "" && getElementAtCursor()?.parentElement?.parentElement?.classList.contains('protyle-wysiwyg--attr')) {
            return;
        }
        press_enter()
    }
}
// 清空选中的内容: 先剪切, 再增加空行
async function clear_selected_data() {
    // 触发 ctrl+x, 剪切选中的块, 目的是删除原有内容
    document.execCommand('cut');
    // 在上一行下面增加空行
    press_up()
    await add_new_line()
}
// 合并选中的块
async function handle_merge() {
    // 获取当前选中的文本
    let clipboardText = await get_selected_data();
    // 删除空行
    let clipboardTextRet = clipboardText.replace(/^\s*[\r\n]/gm, '');
    // 如果不需要处理, 则直接返回
    if (clipboardTextRet == "" || clipboardText == clipboardTextRet) {
        console.log(clipboardText)
        console.log("不需要处理")
        return;
    }
    // 删除原有内容, 并增加空行
    await clear_selected_data()
    // 粘贴处理后的文本
    await paste_data(clipboardTextRet);
}
// 拆分选中的块
async function handle_split() {
    // 获取当前选中的文本
    let clipboardText = await get_selected_data();

    clipboardTextTmpList = clipboardText.split('\n')
    // 判断是否为空
    clipboardTextRetList = clipboardText.replace(/^\s*[\r\n]/gm, '').split('\n')
    let ret_cnt = clipboardTextRetList.length;
    if (ret_cnt <= 1 || clipboardTextTmpList.length >= ret_cnt*2-1) {
        console.log(clipboardText)
        console.log("不需要处理")
        return;
    }

    // 删除原有内容, 并增加空行
    await clear_selected_data()
    // 粘贴处理后的文本
    for (let idx in clipboardTextRetList) {
        await paste_data(clipboardTextRetList[idx]);
        await add_new_line()
    }
}
// 事件监听
document.addEventListener('keydown', async (event) => {
    // 检查是否按下了 Ctrl + r
    if (event.ctrlKey && event.key === 'r') {
        // event.preventDefault(); // 防止快捷键默认行为
        await handle_merge();
    }
});
// 事件监听
document.addEventListener('keydown', async (event) => {
    // 检查是否按下了 Ctrl + r
    if (event.ctrlKey && event.key === 'q') {
        // event.preventDefault(); // 防止快捷键默认行为
        await handle_split();
    }
});
})()

  • 思源笔记

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

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

    21605 引用 • 85480 回帖 • 3 关注
  • 代码片段

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

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

    42 引用 • 220 回帖

相关帖子

欢迎来到这里!

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

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