思源编辑器输入事件

思源编辑器输入事件

(()=>{
    // 编辑器输入事件
    onEditorInput((editor) => {
        // 获取光标所在元素
        const currEl = getCursorElement();
        console.log('当前元素', currEl);
        // 获取当前块
        const currBlock = currEl.closest('[data-type]');
        console.log('当前块', currBlock);
    });
  
    // 编辑器输入事件
    function onEditorInput(callback) {
        whenElementExist(isMobile()?'body':'.layout__center').then(async element => {
            // 等待笔记列表加载完毕
            await sleep(40);
            // 监听编辑器加载事件
            observeDomChange(element, async (mutation) => {
                if (mutation.target.classList?.contains("protyle-wysiwyg")) {
                   const editor = mutation.target;
                    if(editor && editor.closest){
                        // 等待编辑器加载完毕
                        const protyle = editor.closest(".protyle");
                        if(protyle.dataset.loading !== 'finished'){
                            await whenElementExist(()=>editor?.closest(".protyle") === 'finished');
                        }
                        if(!editor.getAttribute('custom-listened')){
                            editor.setAttribute('custom-listened', true);
                            //console.log('listen editor');
                            editor.addEventListener('input', ()=>{
                                //console.log('editor inputed');
                                callback(editor);
                            })
                        }
                    }
                }
            });
        });
    }
    // 获取光标所在元素
    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 observeDomChange(selector, callback) {
        // 定义一个回调函数,当DOM发生变化时调用
        const onChange = function(mutationsList, observer) {
            for (const mutation of mutationsList) {
                if (mutation.type === 'childList') {
                    callback(mutation);
                }
            }
        };
        // 创建一个观察器实例,并传入回调函数
        const observer = new MutationObserver(onChange);
        // 配置观察选项:指定需要观察哪些变动
        const config = { attributes: false, childList: true, subtree: true };
        // 获取目标节点
        const targetNode = typeof selector === 'string' ? document.querySelector(selector) : selector;
        // 如果目标节点存在,则开始观察
        if (targetNode) {
            observer.observe(targetNode, config);
        }
        // 返回一个函数,用于停止观察
        return () => {
            observer.disconnect();
        };
    }
    // 是否手机端
    function isMobile() {
        return !!document.getElementById("sidebar");
    }
    // 延迟执行
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
    // 等待元素渲染完成后执行
    function whenElementExist(selector) {
        return new Promise(resolve => {
            const checkForElement = () => {
                let element = null;
                if (typeof selector === 'function') {
                    element = selector();
                } else {
                    element = document.querySelector(selector);
                }
                if (element) {
                    resolve(element);
                } else {
                    requestAnimationFrame(checkForElement);
                }
            };
            checkForElement();
        });
    }
})();

see https://ld246.com/article/1728483659211

image.png

留下你的脚步
推荐阅读