如何真的关闭 JS 代码片段?

在写一个 JS ,但我发现关闭代码片段之后这个 JS 还在运行,咋整?

启用代码片段之后会添加一个元素,这个元素在关闭代码片段时会移除,但 JS 却还会持续运行:

image.png

  • 思源笔记

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

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

    22212 引用 • 88744 回帖 • 7 关注
  • Q&A

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

    8050 引用 • 36778 回帖 • 162 关注
2 操作
JeffreyChen 在 2024-09-21 23:18:31 更新了该帖
JeffreyChen 在 2024-09-21 23:14:59 更新了该帖

相关帖子

被采纳的回答
  • wilsons 2

    我通过这个函数实现了判断代码片段是否关闭,不知是否你想要的效果。

    // 判断脚本是否开启
    // 通过唯一标志符判断是否启用此脚本,下面的uuid不要删除,也可以改成其他全局唯一字符串
    // 如果性能更好,可以使用脚本id和这个方法相结合,即把这个uuid改为脚本id,然后先用脚本id判断脚本是否存在,再用keyword判断
    // 也可以通过/api/snippet/getSnippet来判断脚本开启状态,这里采用判断脚本是否存在的方式
    // 调用方式 isEnabled()
    // b6fb408a-d400-4874-b357-06fcdce67ca6
    function isEnabled(keyword = 'b6fb408a-d400-4874-b357-06fcdce67ca6') {
      if(!siyuan.config.snippet.enabledJS) return false;
      const scripts = document.getElementsByTagName('script');
      for (var i = 0; i < scripts.length; i++) {
          if (scripts[i].textContent.indexOf('// ' + keyword) !== -1) {
              return true;
          }
      }
      return false;
    }
    

    然后在 MutationObserver 回调中添加判断

    if(!isEnabled()) {
      if(observer) observer.disconnect();
      if(timeoutId) clearTimeout(timeoutId);
      if(animationFrameRequestId) cancelAnimationFrame(animationFrameRequestId);
      return;
    }
    

    如图

    image.png

    效果

    r59.gif

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • @wilsons 你懂吗?

    1 回复
  • 在插件里可以监听卸载事件,不知道代码片段有没有相关事件,没有的话自行监听一下。

    防止开发时重复执行的话可以一个用全局变量,插件代码执行时创建一个唯一标志,例如当前时间,当全局变量与该标志不一致时就知道执行新代码了,于是老代码就知道要清理自己了

  • wilsons 1

    楼上说的没错,这要看代码的具体内容是什么。

    如果绑定了事件,需要解绑,我通常是执行前先解绑再绑定,这样不用担心可能的意外执行被多次绑定的问题。

    如果有定时任务啥的需要给个取消的条件,如果不好确定,最方便的是通过全局变量。

    如果有监听,要先 disconnect。

    1 回复
  • zxhd86 1 赞同

    很简单,刷新一下思源就行了。

    建议使用插件 开发者工具 的重载窗口功能。

    1 回复
  • 代码是这个,有定时器和 MutationObserver :

    [js] 限制数据库换行文本最大行数

    1 回复
    1 操作
    JeffreyChen 在 2024-09-22 01:47:50 更新了该回帖
  • wilsons 2

    我通过这个函数实现了判断代码片段是否关闭,不知是否你想要的效果。

    // 判断脚本是否开启
    // 通过唯一标志符判断是否启用此脚本,下面的uuid不要删除,也可以改成其他全局唯一字符串
    // 如果性能更好,可以使用脚本id和这个方法相结合,即把这个uuid改为脚本id,然后先用脚本id判断脚本是否存在,再用keyword判断
    // 也可以通过/api/snippet/getSnippet来判断脚本开启状态,这里采用判断脚本是否存在的方式
    // 调用方式 isEnabled()
    // b6fb408a-d400-4874-b357-06fcdce67ca6
    function isEnabled(keyword = 'b6fb408a-d400-4874-b357-06fcdce67ca6') {
      if(!siyuan.config.snippet.enabledJS) return false;
      const scripts = document.getElementsByTagName('script');
      for (var i = 0; i < scripts.length; i++) {
          if (scripts[i].textContent.indexOf('// ' + keyword) !== -1) {
              return true;
          }
      }
      return false;
    }
    

    然后在 MutationObserver 回调中添加判断

    if(!isEnabled()) {
      if(observer) observer.disconnect();
      if(timeoutId) clearTimeout(timeoutId);
      if(animationFrameRequestId) cancelAnimationFrame(animationFrameRequestId);
      return;
    }
    

    如图

    image.png

    效果

    r59.gif

    1 回复
    1 操作
    wilsons 在 2024-09-22 07:08:11 更新了该回帖
  • 对,非常感谢。另外我改为只遍历 head 元素下的 script 标签:

    // 判断脚本是否开启
    // 通过唯一标志符判断是否启用此脚本,下面的uuid不要删除,也可以改成其他全局唯一字符串
    // 如果性能更好,可以使用脚本id和这个方法相结合,即把这个uuid改为脚本id,然后先用脚本id判断脚本是否存在,再用keyword判断
    // 也可以通过/api/snippet/getSnippet来判断脚本开启状态,这里采用判断脚本是否存在的方式
    // 调用方式 isEnabled()
    // b6fb408a-d400-4874-b357-06fcdce67ca6
    function isEnabled(keyword = 'b6fb408a-d400-4874-b357-06fcdce67ca6') {
        if(!siyuan.config.snippet.enabledJS) return false;
        const scripts = document.head.getElementsByTagName('script'); // 只遍历 head 元素下的 script 标签
        for (var i = 0; i < scripts.length; i++) {
            if (scripts[i].textContent.indexOf('// ' + keyword) !== -1) {
                return true;
            }
        }
        return false;
    }
    
    1 回复
  • wilsons 3

    👍 我在你的基础上,对这个函数进一步优化,加入了通过 id 判断,遍历脚本仅执行一次。

    // 判断脚本是否开启
    // 通过唯一标志符判断是否启用此脚本,注释中的uuid不要删除,也可以改成其他全局唯一字符串
    // 也可以通过/api/snippet/getSnippet来判断脚本开启状态,这里采用判断脚本是否存在的方式
    // 调用方式 isEnabled()
    let scriptId = '';
    function isEnabled(keyword = 'b6fb408a-d400-4874-b357-06fcdce67ca6') {
      if(!siyuan.config.snippet.enabledJS) return false;
      const script = scriptId ? document.getElementById(scriptId) : null;
      if(script) return true;
      const scripts = document.head.getElementsByTagName('script');
      for (var i = 0; i < scripts.length; i++) {
          // b6fb408a-d400-4874-b357-06fcdce67ca6
          if (scripts[i].textContent.indexOf('// ' + keyword) !== -1) {
            scriptId = scripts[i].id;
            return true;
          }
      }
      return false;
    }
    

    另外,建议不用对整个 body 进行监控,监控 .layout__center 应该就足够了。

    1 回复
  • EmberSky

    我调的时候, 一般也是重新加载, 我还特意在顶栏加了重新加载的按钮

    image.png

  • wilsons 1

    @JeffreyChen

    把 isEnabled()函数中的

    const scripts = document.head.getElementsByTagName('script');

    改为

    const scripts = document.head.querySelectorAll("script[id^=snippetJS]");

    可大大提高第一次遍历时的性能,毕竟系统库函数啥的文本量还是巨大的,而代码片段的代码往往很小。

请输入回帖内容 ...
JeffreyChen
思源是支持 Markdown 语法输入的块编辑器,而不是 Markdown 文件编辑器; 思源笔记同步教程:ld246.com/article/1692089679062

推荐标签 标签

  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 41 关注
  • 域名

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

    43 引用 • 208 回帖
  • OnlyOffice
    4 引用
  • Facebook

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

    4 引用 • 15 回帖 • 453 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    682 引用 • 535 回帖
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 337 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 52 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    176 引用 • 815 回帖
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 153 关注
  • Mobi.css

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

    1 引用 • 6 回帖 • 735 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 286 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 2 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    53 引用 • 40 回帖
  • 996
    13 引用 • 200 回帖 • 7 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    26 引用 • 84 回帖
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 3 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 535 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 481 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 155 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    6 引用 • 14 回帖 • 1 关注
  • 国际化

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

    8 引用 • 26 回帖
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 746 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1792 回帖
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1705 回帖
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 8 关注