js 代码如何实现根据输入的内容自动给其块加上属性或自定义属性

例如:

但我输入的文字符合自己设定的正则表达式的规则,则自动给当前块加上相关属性

例如当我笔记中存在成都时,自动给当前块加上“地点”:“成都”的属性

  • 思源笔记

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

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

    22210 引用 • 88737 回帖 • 7 关注
  • Q&A

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

    8048 引用 • 36773 回帖 • 162 关注

相关帖子

被采纳的回答
  • wilsons 1 1 赞同

    监听编辑器输入事件,仅供参考

    (()=>{
        // 编辑器输入事件
        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")) {
                        console.log(mutation.target);
                       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();
            });
        }
    })();
    

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • 监听编辑事件,符合正则时调用 api 写块属性

    1 回复
  • 其他回帖
  • stevehfut
    作者

    可以提供监听思源编辑事件的代码吗

    1 回复
  • wilsons 1 1 赞同 1 评论

    监听编辑器输入事件,仅供参考

    (()=>{
        // 编辑器输入事件
        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")) {
                        console.log(mutation.target);
                       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();
            });
        }
    })();
    
    万分感谢!!
    stevehfut

推荐标签 标签

  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 481 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 470 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 734 关注
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    36 引用 • 35 回帖 • 1 关注
  • Q&A

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

    8048 引用 • 36771 回帖 • 161 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖
  • Dubbo

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

    60 引用 • 82 回帖 • 599 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 1 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    130 引用 • 793 回帖
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 351 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    286 引用 • 729 回帖
  • sts
    2 引用 • 2 回帖 • 196 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 2 关注
  • Linux

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

    941 引用 • 943 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    41 引用 • 130 回帖 • 264 关注
  • OnlyOffice
    4 引用
  • 996
    13 引用 • 200 回帖 • 7 关注
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 658 关注
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • CodeMirror
    1 引用 • 2 回帖 • 128 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    77 引用 • 390 回帖
  • 创业

    你比 99% 的人都优秀么?

    84 引用 • 1399 回帖
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • Kotlin

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

    19 引用 • 33 回帖 • 62 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 454 关注