Wilson@思源

目 录

ctrl+w不关闭锁定标签代码片段

js
// see https://ld246.com/article/1723109908986 (()=>{ // 注入样式,模拟激活标签的样式,可根据自己的样式进行调整 addStyle(` .layout__wnd--active .layout-tab-bar .item--pin--focus:after { background-color: var(--b3-theme-primary); } .layout-tab-bar .item--pin--focus:after { content: ""; width: 100%; height: 3px; border-radius: var(--b3-border-radius); bottom: 0; position: absolute; background-color: var(--b3-theme-background-light); } `); // 是否在最近打开文档对话框中,将钉住标签移动到当前焦点的下面,默认不移动,改为true时则移动 const isMovePinTabToFocusNextInRecentlyDialog = true; // 是否在标签切换对话框中,将钉住标签移动到当前焦点的下面,默认不移动,改为true时则移动 const isMovePinTabToFocusNextInTabSwitchDialog = true; //////////////// 以下代码,不涉及样式调整,非必要勿动 ////////////////////// // 等待标签页容器渲染完成后开始监听 whenElementExist('.layout__center').then(async element => { // 记录按键前的数据状态 let originalValues = {}; // 当按ctrl+w时,临时修改item--focus为item--pin--focus document.addEventListener('keydown', function(event) { if ((event.ctrlKey || event.metaKey) && event.key === 'w') { // 临时修改item--focus为item--pin--focus const focusPinTab = element.querySelector('.layout-tab-bar .item--pin.item--focus'); if(focusPinTab){ focusPinTab.classList.remove('item--focus'); focusPinTab.classList.add('item--pin--focus'); } // 临时修改activetime为0,值为0可以避免被获得焦点 if(Object.keys(originalValues).length === 0) { const items = element.querySelectorAll('.layout-tab-bar .item--pin'); let maxActivetimeItem = null; let maxActivetime = 0; items.forEach(item => { originalValues[item.getAttribute("data-id")] = item.dataset.activetime; if(item.dataset.activetime > maxActivetime){ maxActivetime = item.dataset.activetime; maxActivetimeItem = item; } item.dataset.activetime = 0; }); // 把最后激活的文档设为下一个焦点 if(maxActivetimeItem) maxActivetimeItem.dataset.activetime = 1; } } }, { capture: true }); // 当按释放按键是,恢复item--pin--focus为item--focus document.addEventListener('keyup', function(event) { // 恢复item--pin--focus为item--focus const focusPinTab = element.querySelector('.layout-tab-bar .item--pin.item--pin--focus'); if(focusPinTab){ focusPinTab.classList.remove('item--pin--focus'); focusPinTab.classList.add('item--focus'); } // 恢复activetime的值 if(Object.keys(originalValues).length > 0) { const items = element.querySelectorAll('.layout-tab-bar .item--pin'); items.forEach(item => { if(item.dataset.activetime <= 1) item.dataset.activetime = originalValues[item.getAttribute("data-id")]; }); //清空originalValues Object.keys(originalValues).forEach(key => { delete originalValues[key]; }); } }, true); // 监听最近打开文档 和 页签切换 if(isMovePinTabToFocusNextInRecentlyDialog || isMovePinTabToFocusNextInTabSwitchDialog) { observeDialogShow((node, dialog)=>{ // 监听最近打开文档 if(dialog === 'dialog-recentdocs'){ // 获取所有钉住的标签 const pinTabNodeIds = getAllPinTabNodeIds(); // 把所有最近文档的钉住标签,移动到当前焦点的下面 movePinTabItemToFocusTabNext(node, pinTabNodeIds); } // 监听页签切换 if(dialog === 'dialog-switchtab'){ // 获取所有钉住的标签 const pinTabNodeIds = getAllPinTabNodeIds(); // 把所有最近文档的钉住标签,移动到当前焦点的下面 movePinTabItemToFocusTabNext(node, pinTabNodeIds); } }); } }); // 获取所有的指定标签的nodeId function getAllPinTabNodeIds() { const pinTabs = document.querySelectorAll(".layout__center .layout-tab-bar li.item--pin"); let pinTabNodeIds = []; pinTabs.forEach(pin => { let initData = pin.getAttribute("data-initdata"); if(initData){ // 初始化时的数据 initData = JSON.parse(initData); if(initData && initData.blockId) { pinTabNodeIds.push(initData.blockId); } } else { // 内容加载后的数据 const dataId = pin.getAttribute("data-id"); const parents = pin.closest("div.fn__flex"); const nodeId = parents?.nextElementSibling?.querySelector('div[data-id="'+dataId+'"] .protyle-breadcrumb__item svg.popover__block')?.getAttribute("data-id"); if(nodeId) { pinTabNodeIds.push(nodeId); } } }); return pinTabNodeIds; } // 移动最近打开文档或文档切换列表的node-id在pinTabNodeIds中的元素到当前焦点的下面 async function movePinTabItemToFocusTabNext(node, pinTabNodeIds) { let ulElement = null; let focusElement = null; await whenElementExist(()=>{ ulElement = node.querySelector("ul.b3-list--background.fn__flex-1"); focusElement = ulElement?.querySelector("li.b3-list-item--focus"); return ulElement && focusElement; }); pinTabNodeIds.reverse(); // 遍历 pinTabNodeIds 数组 pinTabNodeIds.forEach(nodeId => { // 查找具有相应 data-node-id 的 li 元素 const item = ulElement.querySelector(`li[data-node-id="${nodeId}"]`); if (item) { // 将 item 插入到 focusElement 后面 focusElement.parentElement.insertBefore(item, focusElement.nextSibling); } }); } // 监听对话框 function observeDialogShow(callback) { // 创建 MutationObserver 实例 const observer = new MutationObserver((mutationsList) => { for (let mutation of mutationsList) { if (mutation.type === 'childList') { // 遍历新增的子元素 for (let node of mutation.addedNodes) { if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'div') { if (node.hasAttribute('data-key') && node.getAttribute('data-key') === 'dialog-recentdocs') { if(typeof callback === 'function') callback(node, 'dialog-recentdocs'); } if (node.hasAttribute('data-key') && node.getAttribute('data-key') === 'dialog-switchtab') { if(typeof callback === 'function') callback(node, 'dialog-switchtab'); } } } } } }); // 配置 MutationObserver const config = { childList: true, }; // 开始观察 body 的子元素 observer.observe(document.body, config); // observer.disconnect() } // 延迟执行 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(); }); } // 注入样式 function addStyle(styleContent) { // 获取现有的