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

例如:

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

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

  • 思源笔记

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

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

    21614 引用 • 85520 回帖 • 1 关注
  • Q&A

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

    7755 引用 • 35325 回帖 • 182 关注
被采纳的回答
  • 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();
            });
        }
    })();
    

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • 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
  • 其他回帖
  • 监听编辑事件,符合正则时调用 api 写块属性

    1 回复
  • stevehfut
    作者

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

    1 回复

推荐标签 标签

  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    12 引用 • 54 回帖 • 156 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 232 回帖
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 8 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    176 引用 • 994 回帖
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    70 引用 • 533 回帖 • 770 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    179 引用 • 407 回帖 • 493 关注
  • V2Ray
    1 引用 • 15 回帖 • 1 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 317 关注
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖 • 1 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    336 引用 • 682 回帖 • 2 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    148 引用 • 257 回帖 • 1 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 162 关注
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 212 关注
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    727 引用 • 1323 回帖 • 20 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 139 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 1 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    11 引用 • 38 回帖 • 97 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖 • 3 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 511 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • 强迫症

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

    15 引用 • 161 回帖