// ==UserScript== // @name 飞书文档一级目录折叠助手(优化版) // @namespace http://tampermonkey.net/ // @version 1.1 // @description 飞书文档一级目录智能折叠助手,页面加载后自动折叠所有一级目录,适配SPA动态加载/异步渲染,支持Ctrl+Alt+减号快捷键一键切换目录展开/收起状态,带悬浮式状态视觉反馈,精准识别一级目录不影响多级目录,⚠️已知问题:上滑侧边目录栏会触发自动折叠逻辑 // @author anyphasy // @icon http://mms0.baidu.com/it/u=179192646,1445218616&fm=253&app=120&f=JPEG?w=243&h=243 // @match https://*.feishu.cn/wiki/* // @run-at document-idle // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; // 添加样式 GM_addStyle(` #feishu-collapsor-status { position: fixed; top: 88px; left: 20px; background: #2c7cff; color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px; font-weight: bold; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); z-index: 9999; opacity: 0; transform: translateY(-10px); transition: all 0.3s ease; } #feishu-collapsor-status.show { opacity: 1; transform: translateY(0); } #feishu-collapsor-status.collapsed { background: #2c7cff; } #feishu-collapsor-status.expanded { background: #ff6b6b; #ff6b6b; } `); let initCollapse = false;//一开始没有折叠 // 创建状态指示器 const statusIndicator = document.createElement('div'); statusIndicator.id = 'feishu-collapsor-status'; statusIndicator.textContent = '目录状态: 收起'; statusIndicator.classList.add('collapsed'); document.body.appendChild(statusIndicator); // 显示状态消息 function showStatus(message, isCollapsed) { statusIndicator.textContent = `目录状态: ${message}`; statusIndicator.classList.toggle('collapsed', isCollapsed); statusIndicator.classList.toggle('expanded', !isCollapsed); statusIndicator.classList.add('show'); setTimeout(() => statusIndicator.classList.remove('show'), 2000); } // 获取所有一级目录元素(优化版) function getLevel1Items() { return document.querySelectorAll('li.catalogue__list-item.indent-level-1.heading-1.collapsible'); } // 折叠所有一级目录(优化版) function collapseAll() { const items = getLevel1Items(); if (!items.length) return false; let processedItems = new Set(); let hasUnprocessed = false; items.forEach(item => { const collapseSpan = item.querySelector('span.catalogue__item-collapse:not(.collapsed)'); const textSpan = item.querySelector('span.text'); if (collapseSpan && textSpan) { const itemId = textSpan.textContent; if (!processedItems.has(itemId)) { processedItems.add(itemId); console.log(`${itemId} -> 收起了`); collapseSpan.click(); // 验证是否成功收起 setTimeout(() => { if (item.querySelector('span.catalogue__item-collapse.collapsed')) { console.log(`${itemId} -> 成功收起了`); } else { console.log(`${itemId} -> 收起失败,将重试`); hasUnprocessed = true; } }, 100); } } }); return !hasUnprocessed; } // 展开所有一级目录(优化版) function expandAll() { const items = getLevel1Items(); if (!items.length) return false; let processedItems = new Set(); let hasUnprocessed = false; items.forEach(item => { const collapseSpan = item.querySelector('span.catalogue__item-collapse.collapsed'); const textSpan = item.querySelector('span.text'); if (collapseSpan && textSpan) { const itemId = textSpan.textContent; if (!processedItems.has(itemId)) { processedItems.add(itemId); console.log(`${itemId} -> 展开了`); collapseSpan.click(); // 验证是否成功展开 setTimeout(() => { if (item.querySelector('span.catalogue__item-collapse:not(.collapsed)')) { console.log(`${itemId} -> 成功展开了`); } else { console.log(`${itemId} -> 展开失败,将重试`); hasUnprocessed = true; } }, 100); } } }); return !hasUnprocessed; } // 切换所有一级目录状态(优化版) function toggleAll() { const items = getLevel1Items(); if (!items.length) { console.log('没有找到一级目录'); return; } // 检查是否有至少一个展开的目录 let shouldCollapse = false; for (const item of items) { if (item.querySelector('span.catalogue__item-collapse:not(.collapsed)')) { shouldCollapse = true; break; } } if (shouldCollapse) { if (collapseAll()) { showStatus('收起', true); } else { showStatus('部分收起失败', false); } } else { if (expandAll()) { showStatus('展开', false); } else { showStatus('部分展开失败', true); } } } // 优化后的初始化函数 function init() { const maxWaitTime = 20000; // 延长到20秒 const startTime = Date.now(); let lastItemCount = 0; let stableCount = 0; const tryCollapse = () => { const now = Date.now(); if (now - startTime > maxWaitTime) { console.log('飞书目录折叠:达到最大等待时间'); if (lastItemCount > 0) { collapseAll(); showStatus('自动收起', true); } return; } const currentItems = getLevel1Items(); const currentCount = currentItems.length; // 如果数量增加,重置稳定计数器 if (currentCount > lastItemCount) { lastItemCount = currentCount; stableCount = 0; } // 如果数量相同,增加稳定计数器 else if (currentCount === lastItemCount && currentCount > 0) { stableCount++; } // 如果连续3次检查数量稳定且有目录,则执行折叠 if (stableCount >= 3) { collapseAll(); initCollapse = true; console.log('initCollapse设置为true'); showStatus('自动收起', true); } else { setTimeout(tryCollapse, 500); } }; setTimeout(tryCollapse, 3000); // 3秒后开始尝试 } // 添加MutationObserver监听DOM变化 const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.addedNodes.length) { const hasNewItems = Array.from(mutation.addedNodes).some(node => { return node.nodeType === 1 && node.matches('li.catalogue__list-item.indent-level-1.heading-1.collapsible'); }); if (hasNewItems && initCollapse === false) { console.log('检测到新的一级目录加载,重新折叠'); setTimeout(collapseAll, 300); } } }); }); // 开始观察文档变化 observer.observe(document.body, { childList: true, subtree: true }); // 添加快捷键监听 document.addEventListener('keydown', function (e) { if (e.ctrlKey && e.altKey && e.key === '-') { toggleAll(); e.preventDefault(); e.stopPropagation(); } }, true); // 初始化脚本 if (document.readyState === 'complete' || document.readyState === 'interactive') { setTimeout(init, 0); } else { document.addEventListener('DOMContentLoaded', init); } })();