您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
自动展开任意网站的折叠内容,智能识别展开按钮,避免误触跳转链接。
当前为
// ==UserScript== // @name 网页自动展开(全站适用·防误跳转) // @version 1.0.3 // @description 自动展开任意网站的折叠内容,智能识别展开按钮,避免误触跳转链接。 // @namespace Kiwifruit13 // @match *://*/* // @run-at document-idle // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; // ============= 排除名单(在此添加已知有问题的网站) ============= const EXCLUDE_HOSTS = [ 'www.toutiao.com', 'm.toutiao.com', 'zh.moegirl.org.cn', 'moegirl.org.cn', 'www.zhihu.com', // 可选:若知乎展开异常也可排除 'v.douyin.com', // 抖音网页版可能受影响 // 可继续添加其他问题站点 ]; // 检查当前页面是否在排除名单中 const currentHost = location.hostname; if (EXCLUDE_HOSTS.some(host => currentHost === host || currentHost.endsWith('.' + host))) { return; // 直接退出,不执行任何逻辑 } // ============= 以下为原有自动展开逻辑 ============= const EXPANDED_ATTR = 'data-auto-expanded'; const CLICKED_ATTR = 'data-auto-clicked'; const EXPAND_KEYWORDS = [ '展开', '查看', '阅读', '显示', '更多', '全文', '全部', '继续', 'Read', 'More', 'Full', 'Expand', 'Continue', 'Show', 'View' ]; function isSafeExpandButton(el) { if (!el || el.nodeType !== 1) return false; if (el.hasAttribute(CLICKED_ATTR)) return false; const rect = el.getBoundingClientRect(); if (rect.height > 60 || rect.width > 300) return false; const text = (el.innerText || el.textContent || '').trim(); if (text.length === 0 || text.length > 40) return false; if (/登录|关注|订阅|点赞|收藏|分享|评论|回复|举报|广告|下载|安装|打开APP|跳转|前往/i.test(text)) { return false; } const hasKeyword = EXPAND_KEYWORDS.some(kw => text.includes(kw)); if (!hasKeyword) return false; if (el.tagName === 'A') { const href = el.getAttribute('href') || ''; if (href && !/^(\s*#|javascript:|mailto:|tel:)/i.test(href)) { return false; } } return el.tagName === 'BUTTON' || el.tagName === 'A' || el.role === 'button' || el.onclick || el.classList.length > 0; } function isCollapsedContainer(el) { if (el.hasAttribute(EXPANDED_ATTR)) return false; if (el.tagName === 'BODY' || el.tagName === 'HTML') return false; // 保护 body/html const cs = window.getComputedStyle(el); const maxHeight = parseFloat(cs.maxHeight); const hasMaxHeight = maxHeight > 0 && maxHeight < 600; const hasOverflowHidden = cs.overflow === 'hidden' || cs.overflowY === 'hidden'; const isTaller = el.scrollHeight > el.clientHeight + 20; // 防止误伤滚动容器 const rect = el.getBoundingClientRect(); const isFullViewport = rect.height >= window.innerHeight * 0.85; const isScrollable = /auto|scroll/.test(cs.overflowY); if (isFullViewport && isScrollable) return false; return hasMaxHeight && hasOverflowHidden && isTaller; } function removeMask(el) { if (!el.className) return; const cls = el.className.replace(/\s+/g, '.'); const tag = el.tagName.toLowerCase(); const selector = `${tag}${cls ? '.' + cls : ''}`; const style = document.createElement('style'); style.textContent = ` ${selector}::before, ${selector}::after { display: none !important; content: "" !important; background: transparent !important; } `; document.head.appendChild(style); } function autoExpand() { document.querySelectorAll('button, a, [role="button"], div, span, p').forEach(el => { if (isSafeExpandButton(el)) { try { el.click(); el.setAttribute(CLICKED_ATTR, 'true'); } catch (e) { /* ignore */ } } }); document.querySelectorAll('div, section, article, p, .content, .text').forEach(el => { if (isCollapsedContainer(el)) { el.style.maxHeight = 'none'; el.style.height = 'auto'; el.style.overflow = 'visible'; el.setAttribute(EXPANDED_ATTR, 'true'); removeMask(el); } }); } autoExpand(); let observerTimer; const observer = new MutationObserver(() => { clearTimeout(observerTimer); observerTimer = setTimeout(autoExpand, 400); }); observer.observe(document.body, { childList: true, subtree: true }); let scrollTimer; window.addEventListener('scroll', () => { clearTimeout(scrollTimer); scrollTimer = setTimeout(autoExpand, 400); }); if (document.readyState === 'complete') { setTimeout(autoExpand, 1000); } else { window.addEventListener('load', () => setTimeout(autoExpand, 1000)); } })();