您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在页面上选择元素进行折叠并增加折叠展开按钮
// ==UserScript== // @name 添加自定义折叠按钮 // @namespace http://tampermonkey.net/ // @version 20250816.1 // @description 在页面上选择元素进行折叠并增加折叠展开按钮 // @author atakhalo // @match *://*/* // @grant GM_registerMenuCommand // @license MIT // ==/UserScript== (function () { 'use strict'; let target = null; let moveSelect = null; // 添加样式 const style = document.createElement('style'); style.textContent = ` .fold-highlight { outline: 3px dashed #ff6600 !important; cursor: pointer !important; position: relative; z-index: 9999; } .fold-highlight::after { content: "点击折叠(alt +-*/进行切换父子兄弟)"; position: absolute; top: -25px; left: 0; background: #ff6600; color: white; padding: 2px 6px; font-size: 12px; border-radius: 4px; white-space: nowrap; } .fold-expand-marker { margin-top: 12px; height: 26px; margin-bottom: 20px; // color: white; // width: 26px; display: flex; font-size: 16px; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.2); // z-index: 10000; transition: all 0.2s; } // .fold-expand-marker:hover { // // transform: scale(1.1); // // box-shadow: 0 4px 10px rgba(0,0,0,0.3); // } // .fold-expand-marker::after { // content: "展开"; // position: absolute; // top: -25px; // right: -5px; // background: #4a6cf7; // color: white; // padding: 2px 6px; // font-size: 12px; // border-radius: 4px; // white-space: nowrap; // opacity: 0; // transition: opacity 0.2s; // } // .fold-expand-marker:hover::after { // opacity: 1; // } #foldCounter { position: fixed; top: 80px; left: 25px; background: rgba(255,255,255,0.9); border: 1px solid #4a6cf7; padding: 5px 10px; border-radius: 20px; font-size: 12px; z-index: 9999; box-shadow: 0 2px 8px rgba(0,0,0,0.1); display: none; } #foldStatus { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.7); color: white; padding: 8px 16px; border-radius: 4px; font-size: 14px; z-index: 10000; display: none; } `; document.head.appendChild(style); // 创建状态提示 const statusMsg = document.createElement('div'); statusMsg.id = 'foldStatus'; document.body.appendChild(statusMsg); // 显示状态消息 function showStatus(message, duration = 2000) { statusMsg.textContent = message; statusMsg.style.display = 'block'; setTimeout(() => { statusMsg.style.display = 'none'; }, duration); } GM_registerMenuCommand('选择折叠', toSelect) GM_registerMenuCommand('取消选择', stopSelect) GM_registerMenuCommand('全部展开', expandAll) GM_registerMenuCommand('全部清除', delAll) function toSelect() { moveSelect = true; showStatus('选择模式已激活 - 点击页面元素进行折叠', 3000); document.body.addEventListener('mousemove', highlightElement); document.body.addEventListener('click', selectElement); document.addEventListener('keydown', handleKey); // document.addEventListener('wheel', handleWheel); document.addEventListener('contextmenu', handleRightClick); } function stopMoveSelect() { moveSelect = false; document.body.removeEventListener('mousemove', highlightElement); } function stopSelect() { showStatus('选择模式已取消', 1500); endSelect(); } function endSelect() { removeHighlights(); stopMoveSelect(); target = null; document.removeEventListener('keydown', handleKey); // document.removeEventListener('wheel', handleWheel); document.body.removeEventListener('click', selectElement); document.removeEventListener('contextmenu', handleRightClick); } // 选择元素进行折叠 function selectElement(e) { if (checkFold(target)) // 已经有折叠按钮了 { } else { foldElement(target); } endSelect(); stopE(e); showStatus('成功折叠', 1500); } function checkFold(e) { const p = e.previousSibling; if (p == null) return; if (p && p.classList && p.classList.contains('fold-expand-marker')) { if (p.isFold === false) { p.click(); } return true; } return false; } // 递归获取元素的前两个汉字 function getFirstTwoChineseChars(element) { if (!element) return ''; let text = ''; for (let node of element.childNodes) { if (node.classList?.contains('fold-expand-marker')) { continue; } if (node.nodeType === Node.TEXT_NODE) { text += node.textContent.trim(); if (text.length >= 4) break; } else if (node.nodeType === Node.ELEMENT_NODE) { text += getFirstTwoChineseChars(node); if (text.length >= 4) break; } } return text.slice(0, 4); } // 折叠元素 function foldElement(el) { // 隐藏元素 el.style.display = 'none'; // 创建展开标记 const expandMarker = document.createElement('div'); expandMarker.className = 'fold-expand-marker'; expandMarker.title = '点击展开'; expandMarker.isFold = true; expandMarker.showText = getFirstTwoChineseChars(el); expandMarker.textContent = expandMarker.showText + '...展开+'; // 悬浮显示被遮挡元素内容 expandMarker.addEventListener('mouseenter', () => { if (expandMarker.isFold === false) // 不是折叠就不显示了 { return; } const preview = document.createElement('div'); preview.className = 'fold-preview'; preview.style.position = 'absolute'; preview.style.zIndex = 9999; preview.style.background = '#fff'; preview.style.border = '1px solid #ccc'; preview.style.padding = '4px 8px'; preview.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)'; preview.textContent = el.textContent.trim().slice(0, 500); document.body.appendChild(preview); const rect = expandMarker.getBoundingClientRect(); preview.style.left = `${rect.left + window.scrollX}px`; preview.style.top = `${rect.top + window.scrollY - preview.offsetHeight - 10}px` // preview.style.bottom = rect.top + 'px'; expandMarker._preview = preview; }); expandMarker.addEventListener('mouseleave', () => { if (expandMarker._preview) { document.body.removeChild(expandMarker._preview); expandMarker._preview = null; } }); // 点击展开 expandMarker.addEventListener('click', (e) => { if (el.style.display !== 'none') { expandMarker.isFold = true el.style.display = 'none'; expandMarker.textContent = expandMarker.showText + '...展开+'; } else { expandMarker.isFold = false el.style.display = ''; expandMarker.textContent = expandMarker.showText + '...折叠-'; } stopE(e); }); const parent = el.parentNode; parent.insertBefore(expandMarker, el); } function expandAll() { const button = document.querySelectorAll(".fold-expand-marker"); button.forEach(element => { if (element.isFold === true) element.click(); }); } function delAll() { const button = document.querySelectorAll(".fold-expand-marker"); button.forEach(element => { if (element.isFold === true) element.click(); element.remove(); }); } // 移除高亮 function removeHighlights() { document.querySelectorAll('.fold-highlight').forEach(el => { el.classList.remove('fold-highlight'); }); } // 高亮元素 function highlightElement(e) { highlightTarget(e.target); } function highlightTarget(newTarget) { target = newTarget; console.log("target" + target) // 排除不需要折叠的元素 if (!target || target === document.documentElement || target === document.body || target.classList.contains('fold-expand-marker')) { removeHighlights(); return; } removeHighlights(); target.classList.add('fold-highlight'); } function handleKey(e) { if (e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey) { if (moveSelect) { stopMoveSelect(); } if (e.key === '+' || e.key === '=') { var newTarget = target.parentNode; TrySetTarget(newTarget, true); // 按理说不会折叠按钮不会是父节点,保底一下 stopE(e); } else if (e.key === '-' || e.key === '_') { var newTarget = target.firstElementChild; TrySetTarget(newTarget, true); stopE(e); } else if (e.key === '*' || e.key === ']') { var newTarget = target.nextElementSibling; TrySetTarget(newTarget, true); stopE(e); } else if (e.key === '/' || e.key === '[') { var newTarget = target.previousElementSibling; TrySetTarget(newTarget, false); stopE(e); } } } // toNext 表示如果当前是折叠按钮,是否向下一个还是向上一个 function IsFoldButton(newTarget, toNext) { if (newTarget.classList.contains('fold-expand-marker')) { if (toNext) { return newTarget.nextElementSibling; } else { return newTarget.previousElementSibling; } } return newTarget; } function TrySetTarget(newTarget, toNext) { newTarget = IsFoldButton(newTarget) if (newTarget != null) { highlightTarget(newTarget, toNext); } else { } } function handleRightClick(e) { stopSelect(); stopE(e); } function stopE(e) { e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); } })();