请问如何通过 api 获得当前所有打开的页签 id

包括所有窗口

  • 思源笔记

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

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

    25953 引用 • 107579 回帖
  • Q&A

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

    9962 引用 • 45253 回帖 • 76 关注

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • 没有 api 可以直接获取的,不过可以通过下面的代码获取
    (支持已加载的,未加载的,钉住的标签,分屏的标签,总之,所有标签都可以获取,但仅支持当前空间和当前窗口,即新窗口打开的不支持,但,每个新窗口打开都会获取当前窗口的,要想汇总所有窗口,可以使用 localstorage 进行窗口间的汇总即可,要想实时还得监听 localstorage 数据变化)

    function getTabIds() { return [...window.siyuan.layout.centerLayout.element.querySelectorAll('[data-type="tab-header"]')].map(tab=>{ const protyle = getInstanceById(tab.dataset.id); let rootId = ''; if(protyle.model) { rootId = protyle.model.editor.protyle.block.rootID; } else { const initData = protyle.headElement.getAttribute("data-initdata"); if (initData) { const initDataObj = JSON.parse(initData); if (initDataObj && initDataObj.instance === "Editor") { rootId = initDataObj.rootId || initDataObj.blockId; } } } return rootId; }); function getInstanceById(id, layout = window.siyuan.layout.centerLayout) { const _getInstanceById = (item, id) => { if (item.id === id) return item; if (!item.children) return; let ret; for (let i = 0; i < item.children.length; i++) { ret = _getInstanceById(item.children[i], id); if (ret) return ret; } }; return _getInstanceById(layout, id); } }
    1 回复
    3 操作
    wilsons 在 2025-05-27 20:40:30 更新了该回帖
    wilsons 在 2025-05-27 20:34:20 更新了该回帖
    wilsons 在 2025-05-27 20:28:50 更新了该回帖
  • 试了一下只能获取当前窗口的

    1 回复
  • image.png

    仅支持当前工作空间,当前窗口的,即新窗口打开的不支持

    但,每个新窗口打开都会获取当前窗口的,要想汇总所有窗口,可以使用 localstorage 进行窗口间的汇总即可,要想实时还得监听 localstorage 数据变化

    1 回复
    2 操作
    wilsons 在 2025-05-27 20:39:54 更新了该回帖
    wilsons 在 2025-05-27 20:35:32 更新了该回帖
  • kobi 2 评论

    安装插件 sy-run-js 后用 runJs.siyuan.getAllModels().editor.map(item=>item.editor.protyle.options.rootId),目前看好像没什么问题,但也只能获取当前窗口的。不过都用插件了,插件里去调用对应的方法会更好。

    这种方法只能获取已加载过的标签,如果刷新页面,那些未点击过的标签无法获取
    wilsons
    @wilsons 确实是这样
    kobi
  • 1 回复
  • 这涉及到多窗口通信问题,最简单的方式是使用 localStorage 监听通信,比如把下面的代码添加到之前代码的任意地方即可

    然后调用 await getAllWindowTabIds()即可

    当然更好的方式是用 postMessage

    这里还可以优化,比如监听可分为 request 和 response 两个,这样就不用 setTimeout 了,时效性更强。

    // 获取所有窗口标签id async function getAllWindowTabIds(delay = 100) { const keyPrefix = '__all_window_tab_ids_'; const noticeKey = keyPrefix + 'notice'; const dataKeyPrefix = keyPrefix + 'data_'; const dataKey = dataKeyPrefix + window.siyuan.ws.app.appId; // 更新数据 const tabIds = getTabIds(); localStorage.setItem(noticeKey, performance.now()); localStorage.setItem(dataKey, JSON.stringify(tabIds)); await new Promise(resolve => setTimeout(resolve, delay)); // 获取所有数据 const keys = Object.keys(localStorage).filter(key => key.startsWith(dataKeyPrefix)); let allTabIds = []; if(keys.length > 0) { for(const key of keys) { let value = localStorage[key]; if(!value) continue; value = JSON.parse(value); if(value.length === 0) continue; localStorage.removeItem(key); allTabIds = [...allTabIds, ...value]; } } // allTabIds = [...new Set(allTabIds)]; // 去重 return allTabIds; } // 监听tab数据变化 if(!window.__hasListenedStorage) { window.__hasListenedStorage = true; const keyPrefix = '__all_window_tab_ids_'; const noticeKey = keyPrefix + 'notice'; const dataKeyPrefix = keyPrefix + 'data_'; const dataKey = dataKeyPrefix + window.siyuan.ws.app.appId; if(!localStorage.getItem(noticeKey)) localStorage.setItem(noticeKey, performance.now()); window.addEventListener('storage', function (event) { if (event.key === noticeKey) { const tabIds = getTabIds(); localStorage.setItem(dataKey, JSON.stringify(tabIds)); } }); }
    1 操作
    wilsons 在 2025-05-28 10:41:40 更新了该回帖
请输入回帖内容 ...

推荐标签 标签

  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 4 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    29 引用 • 202 回帖 • 27 关注
  • CSDN

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

    14 引用 • 155 回帖
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖 • 1 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    10 引用 • 15 回帖 • 8 关注
  • 叶归
    11 引用 • 50 回帖 • 20 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    211 引用 • 358 回帖
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 372 关注
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    171 引用 • 1537 回帖 • 1 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • CodeMirror
    2 引用 • 17 回帖 • 167 关注
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 672 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 96 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 396 关注
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    59 引用 • 25 回帖 • 1 关注
  • 支付宝

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

    29 引用 • 347 回帖
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖 • 1 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 106 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 145 关注
  • 笔记

    好记性不如烂笔头。

    310 引用 • 794 回帖
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    230 引用 • 1432 回帖
  • Mobi.css

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

    1 引用 • 6 回帖 • 764 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • 知乎

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

    10 引用 • 66 回帖
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 401 关注