最近论坛出了nested 浏览方式写了一个脚本可开启关闭

2026-04-11 08:321阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

介绍:

  • 开启后替换话题链接并自动重定向到 /nested/topic/xxx?sort=old
  • 替换页面DOM 链接,不会二次跳转
  • 首次安装弹窗引导,可选启用或稍后
油猴脚本如下

// ==UserScript== // @name Linux.do Nested View Redirector // @namespace http://tampermonkey.net/ // @version 1.5 // @description 自动将 linux.do 的话题链接重定向为 nested 视图并按旧到新排序 // @author sunbigfly // @match https://linux.do/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'nested_redirector_enabled'; const WELCOME_KEY = 'nested_redirector_welcomed'; function isEnabled() { return localStorage.getItem(STORAGE_KEY) === '1'; } // ========== 首次安装弹窗 ========== if (!localStorage.getItem(WELCOME_KEY)) { document.addEventListener('DOMContentLoaded', function() { const overlay = document.createElement('div'); Object.assign(overlay.style, { position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(0,0,0,0.4)', zIndex: '99999', display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)', WebkitBackdropFilter: 'blur(4px)', }); const box = document.createElement('div'); Object.assign(box.style, { background: '#fff', borderRadius: '16px', padding: '32px', maxWidth: '380px', width: '90%', boxShadow: '0 24px 48px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.08)', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', color: '#1a1a1a', lineHeight: '1.5', animation: 'nested-fadein 0.2s ease-out', }); const style = document.createElement('style'); style.textContent = ` @keyframes nested-fadein { from { opacity: 0; transform: scale(0.96) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } } `; document.head.appendChild(style); box.innerHTML = ` <div style="font-size:15px; font-weight:600; color:#111; margin-bottom:16px;"> Nested View Redirector </div> <div style="font-size:13px; color:#555; margin-bottom:24px;"> 话题页自动切换为嵌套视图,按时间正序排列。<br> 支持所有打开方式,包括中键和右键新标签页。 </div> <div style="display:flex; gap:8px;"> <button id="nested-welcome-enable" style=" flex:1; padding:10px 0; border:none; border-radius:10px; background:#1a1a1a; color:#fff; font-size:13px; font-weight:500; cursor:pointer; transition: opacity 0.15s; ">启用</button> <button id="nested-welcome-later" style=" flex:1; padding:10px 0; border:1px solid #e0e0e0; border-radius:10px; background:transparent; color:#666; font-size:13px; font-weight:500; cursor:pointer; transition: background 0.15s; ">稍后</button> </div> <div style="margin-top:14px; font-size:11px; color:#aaa; text-align:center;"> 可随时通过右下角开关切换 </div> `; overlay.appendChild(box); document.body.appendChild(overlay); function close() { overlay.remove(); localStorage.setItem(WELCOME_KEY, '1'); } document.getElementById('nested-welcome-enable').addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, '1'); close(); location.reload(); }); document.getElementById('nested-welcome-later').addEventListener('click', close); overlay.addEventListener('click', function(e) { if (e.target === overlay) close(); }); }); } // ========== 悬浮开关 ========== function createToggle() { const enabled = isEnabled(); const btn = document.createElement('div'); Object.assign(btn.style, { position: 'fixed', bottom: '20px', right: '20px', zIndex: '99998', width: '40px', height: '40px', borderRadius: '50%', background: enabled ? '#1a1a1a' : '#d4d4d4', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', transition: 'background 0.2s, transform 0.15s', }); btn.title = enabled ? '点击关闭 Nested 重定向' : '点击启用 Nested 重定向'; // 用 SVG 替代 emoji btn.innerHTML = `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/> <polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/> <line x1="4" y1="4" x2="9" y2="9"/> </svg>`; btn.addEventListener('mouseenter', () => btn.style.transform = 'scale(1.08)'); btn.addEventListener('mouseleave', () => btn.style.transform = 'scale(1)'); btn.addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, isEnabled() ? '0' : '1'); location.reload(); }); document.body.appendChild(btn); } if (document.body) createToggle(); else document.addEventListener('DOMContentLoaded', createToggle); // ========== 核心逻辑(仅启用时执行) ========== if (!isEnabled()) return; const TOPIC_REGEX = /\/t\/(?:[^/]+\/)?(\d+)(?:\/\d+)?\/?(?:[?#].*)?$/; function getNestedPath(url) { try { const u = new URL(url, location.origin); if (u.hostname !== 'linux.do' || u.pathname.startsWith('/nested/')) return null; const match = u.pathname.match(TOPIC_REGEX); if (match) return `https://linux.do/nested/topic/${match[1]}?sort=old`; } catch(e) {} return null; } const currentTarget = getNestedPath(location.href); if (currentTarget) { location.replace(currentTarget); return; } function rewriteLink(a) { if (!a.getAttribute('href')) return; const target = getNestedPath(a.href); if (!target || a.href === target) return; if (!a.dataset.originalHref) a.dataset.originalHref = a.href; a.href = target; } function rewriteAll(root) { (root || document).querySelectorAll('a[href*="/t/"]').forEach(rewriteLink); } let rafId = null; function scheduleRewrite() { if (!rafId) rafId = requestAnimationFrame(() => { rafId = null; rewriteAll(); }); } const observer = new MutationObserver(function(mutations) { for (const m of mutations) { if (m.addedNodes.length || (m.type === 'attributes' && m.target.tagName === 'A')) { scheduleRewrite(); return; } } }); function init() { rewriteAll(); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['href'], }); setInterval(() => rewriteAll(), 2000); } if (document.body) init(); else document.addEventListener('DOMContentLoaded', init); ['pushState', 'replaceState'].forEach(method => { const original = history[method]; history[method] = function(state, title, url) { if (url) { const target = getNestedPath(new URL(url, location.origin).href); if (target) { location.href = target; return; } } const ret = original.apply(this, arguments); scheduleRewrite(); return ret; }; }); window.addEventListener('popstate', function() { const target = getNestedPath(location.href); if (target) location.replace(target); else scheduleRewrite(); }); })();

网友解答:
--【壹】--:

介绍:

  • 开启后替换话题链接并自动重定向到 /nested/topic/xxx?sort=old
  • 替换页面DOM 链接,不会二次跳转
  • 首次安装弹窗引导,可选启用或稍后
油猴脚本如下

// ==UserScript== // @name Linux.do Nested View Redirector // @namespace http://tampermonkey.net/ // @version 1.5 // @description 自动将 linux.do 的话题链接重定向为 nested 视图并按旧到新排序 // @author sunbigfly // @match https://linux.do/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'nested_redirector_enabled'; const WELCOME_KEY = 'nested_redirector_welcomed'; function isEnabled() { return localStorage.getItem(STORAGE_KEY) === '1'; } // ========== 首次安装弹窗 ========== if (!localStorage.getItem(WELCOME_KEY)) { document.addEventListener('DOMContentLoaded', function() { const overlay = document.createElement('div'); Object.assign(overlay.style, { position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(0,0,0,0.4)', zIndex: '99999', display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)', WebkitBackdropFilter: 'blur(4px)', }); const box = document.createElement('div'); Object.assign(box.style, { background: '#fff', borderRadius: '16px', padding: '32px', maxWidth: '380px', width: '90%', boxShadow: '0 24px 48px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.08)', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', color: '#1a1a1a', lineHeight: '1.5', animation: 'nested-fadein 0.2s ease-out', }); const style = document.createElement('style'); style.textContent = ` @keyframes nested-fadein { from { opacity: 0; transform: scale(0.96) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } } `; document.head.appendChild(style); box.innerHTML = ` <div style="font-size:15px; font-weight:600; color:#111; margin-bottom:16px;"> Nested View Redirector </div> <div style="font-size:13px; color:#555; margin-bottom:24px;"> 话题页自动切换为嵌套视图,按时间正序排列。<br> 支持所有打开方式,包括中键和右键新标签页。 </div> <div style="display:flex; gap:8px;"> <button id="nested-welcome-enable" style=" flex:1; padding:10px 0; border:none; border-radius:10px; background:#1a1a1a; color:#fff; font-size:13px; font-weight:500; cursor:pointer; transition: opacity 0.15s; ">启用</button> <button id="nested-welcome-later" style=" flex:1; padding:10px 0; border:1px solid #e0e0e0; border-radius:10px; background:transparent; color:#666; font-size:13px; font-weight:500; cursor:pointer; transition: background 0.15s; ">稍后</button> </div> <div style="margin-top:14px; font-size:11px; color:#aaa; text-align:center;"> 可随时通过右下角开关切换 </div> `; overlay.appendChild(box); document.body.appendChild(overlay); function close() { overlay.remove(); localStorage.setItem(WELCOME_KEY, '1'); } document.getElementById('nested-welcome-enable').addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, '1'); close(); location.reload(); }); document.getElementById('nested-welcome-later').addEventListener('click', close); overlay.addEventListener('click', function(e) { if (e.target === overlay) close(); }); }); } // ========== 悬浮开关 ========== function createToggle() { const enabled = isEnabled(); const btn = document.createElement('div'); Object.assign(btn.style, { position: 'fixed', bottom: '20px', right: '20px', zIndex: '99998', width: '40px', height: '40px', borderRadius: '50%', background: enabled ? '#1a1a1a' : '#d4d4d4', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', transition: 'background 0.2s, transform 0.15s', }); btn.title = enabled ? '点击关闭 Nested 重定向' : '点击启用 Nested 重定向'; // 用 SVG 替代 emoji btn.innerHTML = `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/> <polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/> <line x1="4" y1="4" x2="9" y2="9"/> </svg>`; btn.addEventListener('mouseenter', () => btn.style.transform = 'scale(1.08)'); btn.addEventListener('mouseleave', () => btn.style.transform = 'scale(1)'); btn.addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, isEnabled() ? '0' : '1'); location.reload(); }); document.body.appendChild(btn); } if (document.body) createToggle(); else document.addEventListener('DOMContentLoaded', createToggle); // ========== 核心逻辑(仅启用时执行) ========== if (!isEnabled()) return; const TOPIC_REGEX = /\/t\/(?:[^/]+\/)?(\d+)(?:\/\d+)?\/?(?:[?#].*)?$/; function getNestedPath(url) { try { const u = new URL(url, location.origin); if (u.hostname !== 'linux.do' || u.pathname.startsWith('/nested/')) return null; const match = u.pathname.match(TOPIC_REGEX); if (match) return `https://linux.do/nested/topic/${match[1]}?sort=old`; } catch(e) {} return null; } const currentTarget = getNestedPath(location.href); if (currentTarget) { location.replace(currentTarget); return; } function rewriteLink(a) { if (!a.getAttribute('href')) return; const target = getNestedPath(a.href); if (!target || a.href === target) return; if (!a.dataset.originalHref) a.dataset.originalHref = a.href; a.href = target; } function rewriteAll(root) { (root || document).querySelectorAll('a[href*="/t/"]').forEach(rewriteLink); } let rafId = null; function scheduleRewrite() { if (!rafId) rafId = requestAnimationFrame(() => { rafId = null; rewriteAll(); }); } const observer = new MutationObserver(function(mutations) { for (const m of mutations) { if (m.addedNodes.length || (m.type === 'attributes' && m.target.tagName === 'A')) { scheduleRewrite(); return; } } }); function init() { rewriteAll(); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['href'], }); setInterval(() => rewriteAll(), 2000); } if (document.body) init(); else document.addEventListener('DOMContentLoaded', init); ['pushState', 'replaceState'].forEach(method => { const original = history[method]; history[method] = function(state, title, url) { if (url) { const target = getNestedPath(new URL(url, location.origin).href); if (target) { location.href = target; return; } } const ret = original.apply(this, arguments); scheduleRewrite(); return ret; }; }); window.addEventListener('popstate', function() { const target = getNestedPath(location.href); if (target) location.replace(target); else scheduleRewrite(); }); })();

标签:纯水
问题描述:

介绍:

  • 开启后替换话题链接并自动重定向到 /nested/topic/xxx?sort=old
  • 替换页面DOM 链接,不会二次跳转
  • 首次安装弹窗引导,可选启用或稍后
油猴脚本如下

// ==UserScript== // @name Linux.do Nested View Redirector // @namespace http://tampermonkey.net/ // @version 1.5 // @description 自动将 linux.do 的话题链接重定向为 nested 视图并按旧到新排序 // @author sunbigfly // @match https://linux.do/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'nested_redirector_enabled'; const WELCOME_KEY = 'nested_redirector_welcomed'; function isEnabled() { return localStorage.getItem(STORAGE_KEY) === '1'; } // ========== 首次安装弹窗 ========== if (!localStorage.getItem(WELCOME_KEY)) { document.addEventListener('DOMContentLoaded', function() { const overlay = document.createElement('div'); Object.assign(overlay.style, { position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(0,0,0,0.4)', zIndex: '99999', display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)', WebkitBackdropFilter: 'blur(4px)', }); const box = document.createElement('div'); Object.assign(box.style, { background: '#fff', borderRadius: '16px', padding: '32px', maxWidth: '380px', width: '90%', boxShadow: '0 24px 48px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.08)', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', color: '#1a1a1a', lineHeight: '1.5', animation: 'nested-fadein 0.2s ease-out', }); const style = document.createElement('style'); style.textContent = ` @keyframes nested-fadein { from { opacity: 0; transform: scale(0.96) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } } `; document.head.appendChild(style); box.innerHTML = ` <div style="font-size:15px; font-weight:600; color:#111; margin-bottom:16px;"> Nested View Redirector </div> <div style="font-size:13px; color:#555; margin-bottom:24px;"> 话题页自动切换为嵌套视图,按时间正序排列。<br> 支持所有打开方式,包括中键和右键新标签页。 </div> <div style="display:flex; gap:8px;"> <button id="nested-welcome-enable" style=" flex:1; padding:10px 0; border:none; border-radius:10px; background:#1a1a1a; color:#fff; font-size:13px; font-weight:500; cursor:pointer; transition: opacity 0.15s; ">启用</button> <button id="nested-welcome-later" style=" flex:1; padding:10px 0; border:1px solid #e0e0e0; border-radius:10px; background:transparent; color:#666; font-size:13px; font-weight:500; cursor:pointer; transition: background 0.15s; ">稍后</button> </div> <div style="margin-top:14px; font-size:11px; color:#aaa; text-align:center;"> 可随时通过右下角开关切换 </div> `; overlay.appendChild(box); document.body.appendChild(overlay); function close() { overlay.remove(); localStorage.setItem(WELCOME_KEY, '1'); } document.getElementById('nested-welcome-enable').addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, '1'); close(); location.reload(); }); document.getElementById('nested-welcome-later').addEventListener('click', close); overlay.addEventListener('click', function(e) { if (e.target === overlay) close(); }); }); } // ========== 悬浮开关 ========== function createToggle() { const enabled = isEnabled(); const btn = document.createElement('div'); Object.assign(btn.style, { position: 'fixed', bottom: '20px', right: '20px', zIndex: '99998', width: '40px', height: '40px', borderRadius: '50%', background: enabled ? '#1a1a1a' : '#d4d4d4', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', transition: 'background 0.2s, transform 0.15s', }); btn.title = enabled ? '点击关闭 Nested 重定向' : '点击启用 Nested 重定向'; // 用 SVG 替代 emoji btn.innerHTML = `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/> <polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/> <line x1="4" y1="4" x2="9" y2="9"/> </svg>`; btn.addEventListener('mouseenter', () => btn.style.transform = 'scale(1.08)'); btn.addEventListener('mouseleave', () => btn.style.transform = 'scale(1)'); btn.addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, isEnabled() ? '0' : '1'); location.reload(); }); document.body.appendChild(btn); } if (document.body) createToggle(); else document.addEventListener('DOMContentLoaded', createToggle); // ========== 核心逻辑(仅启用时执行) ========== if (!isEnabled()) return; const TOPIC_REGEX = /\/t\/(?:[^/]+\/)?(\d+)(?:\/\d+)?\/?(?:[?#].*)?$/; function getNestedPath(url) { try { const u = new URL(url, location.origin); if (u.hostname !== 'linux.do' || u.pathname.startsWith('/nested/')) return null; const match = u.pathname.match(TOPIC_REGEX); if (match) return `https://linux.do/nested/topic/${match[1]}?sort=old`; } catch(e) {} return null; } const currentTarget = getNestedPath(location.href); if (currentTarget) { location.replace(currentTarget); return; } function rewriteLink(a) { if (!a.getAttribute('href')) return; const target = getNestedPath(a.href); if (!target || a.href === target) return; if (!a.dataset.originalHref) a.dataset.originalHref = a.href; a.href = target; } function rewriteAll(root) { (root || document).querySelectorAll('a[href*="/t/"]').forEach(rewriteLink); } let rafId = null; function scheduleRewrite() { if (!rafId) rafId = requestAnimationFrame(() => { rafId = null; rewriteAll(); }); } const observer = new MutationObserver(function(mutations) { for (const m of mutations) { if (m.addedNodes.length || (m.type === 'attributes' && m.target.tagName === 'A')) { scheduleRewrite(); return; } } }); function init() { rewriteAll(); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['href'], }); setInterval(() => rewriteAll(), 2000); } if (document.body) init(); else document.addEventListener('DOMContentLoaded', init); ['pushState', 'replaceState'].forEach(method => { const original = history[method]; history[method] = function(state, title, url) { if (url) { const target = getNestedPath(new URL(url, location.origin).href); if (target) { location.href = target; return; } } const ret = original.apply(this, arguments); scheduleRewrite(); return ret; }; }); window.addEventListener('popstate', function() { const target = getNestedPath(location.href); if (target) location.replace(target); else scheduleRewrite(); }); })();

网友解答:
--【壹】--:

介绍:

  • 开启后替换话题链接并自动重定向到 /nested/topic/xxx?sort=old
  • 替换页面DOM 链接,不会二次跳转
  • 首次安装弹窗引导,可选启用或稍后
油猴脚本如下

// ==UserScript== // @name Linux.do Nested View Redirector // @namespace http://tampermonkey.net/ // @version 1.5 // @description 自动将 linux.do 的话题链接重定向为 nested 视图并按旧到新排序 // @author sunbigfly // @match https://linux.do/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'nested_redirector_enabled'; const WELCOME_KEY = 'nested_redirector_welcomed'; function isEnabled() { return localStorage.getItem(STORAGE_KEY) === '1'; } // ========== 首次安装弹窗 ========== if (!localStorage.getItem(WELCOME_KEY)) { document.addEventListener('DOMContentLoaded', function() { const overlay = document.createElement('div'); Object.assign(overlay.style, { position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(0,0,0,0.4)', zIndex: '99999', display: 'flex', alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(4px)', WebkitBackdropFilter: 'blur(4px)', }); const box = document.createElement('div'); Object.assign(box.style, { background: '#fff', borderRadius: '16px', padding: '32px', maxWidth: '380px', width: '90%', boxShadow: '0 24px 48px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.08)', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', color: '#1a1a1a', lineHeight: '1.5', animation: 'nested-fadein 0.2s ease-out', }); const style = document.createElement('style'); style.textContent = ` @keyframes nested-fadein { from { opacity: 0; transform: scale(0.96) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } } `; document.head.appendChild(style); box.innerHTML = ` <div style="font-size:15px; font-weight:600; color:#111; margin-bottom:16px;"> Nested View Redirector </div> <div style="font-size:13px; color:#555; margin-bottom:24px;"> 话题页自动切换为嵌套视图,按时间正序排列。<br> 支持所有打开方式,包括中键和右键新标签页。 </div> <div style="display:flex; gap:8px;"> <button id="nested-welcome-enable" style=" flex:1; padding:10px 0; border:none; border-radius:10px; background:#1a1a1a; color:#fff; font-size:13px; font-weight:500; cursor:pointer; transition: opacity 0.15s; ">启用</button> <button id="nested-welcome-later" style=" flex:1; padding:10px 0; border:1px solid #e0e0e0; border-radius:10px; background:transparent; color:#666; font-size:13px; font-weight:500; cursor:pointer; transition: background 0.15s; ">稍后</button> </div> <div style="margin-top:14px; font-size:11px; color:#aaa; text-align:center;"> 可随时通过右下角开关切换 </div> `; overlay.appendChild(box); document.body.appendChild(overlay); function close() { overlay.remove(); localStorage.setItem(WELCOME_KEY, '1'); } document.getElementById('nested-welcome-enable').addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, '1'); close(); location.reload(); }); document.getElementById('nested-welcome-later').addEventListener('click', close); overlay.addEventListener('click', function(e) { if (e.target === overlay) close(); }); }); } // ========== 悬浮开关 ========== function createToggle() { const enabled = isEnabled(); const btn = document.createElement('div'); Object.assign(btn.style, { position: 'fixed', bottom: '20px', right: '20px', zIndex: '99998', width: '40px', height: '40px', borderRadius: '50%', background: enabled ? '#1a1a1a' : '#d4d4d4', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: '0 2px 8px rgba(0,0,0,0.15)', transition: 'background 0.2s, transform 0.15s', }); btn.title = enabled ? '点击关闭 Nested 重定向' : '点击启用 Nested 重定向'; // 用 SVG 替代 emoji btn.innerHTML = `<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/> <polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/> <line x1="4" y1="4" x2="9" y2="9"/> </svg>`; btn.addEventListener('mouseenter', () => btn.style.transform = 'scale(1.08)'); btn.addEventListener('mouseleave', () => btn.style.transform = 'scale(1)'); btn.addEventListener('click', function() { localStorage.setItem(STORAGE_KEY, isEnabled() ? '0' : '1'); location.reload(); }); document.body.appendChild(btn); } if (document.body) createToggle(); else document.addEventListener('DOMContentLoaded', createToggle); // ========== 核心逻辑(仅启用时执行) ========== if (!isEnabled()) return; const TOPIC_REGEX = /\/t\/(?:[^/]+\/)?(\d+)(?:\/\d+)?\/?(?:[?#].*)?$/; function getNestedPath(url) { try { const u = new URL(url, location.origin); if (u.hostname !== 'linux.do' || u.pathname.startsWith('/nested/')) return null; const match = u.pathname.match(TOPIC_REGEX); if (match) return `https://linux.do/nested/topic/${match[1]}?sort=old`; } catch(e) {} return null; } const currentTarget = getNestedPath(location.href); if (currentTarget) { location.replace(currentTarget); return; } function rewriteLink(a) { if (!a.getAttribute('href')) return; const target = getNestedPath(a.href); if (!target || a.href === target) return; if (!a.dataset.originalHref) a.dataset.originalHref = a.href; a.href = target; } function rewriteAll(root) { (root || document).querySelectorAll('a[href*="/t/"]').forEach(rewriteLink); } let rafId = null; function scheduleRewrite() { if (!rafId) rafId = requestAnimationFrame(() => { rafId = null; rewriteAll(); }); } const observer = new MutationObserver(function(mutations) { for (const m of mutations) { if (m.addedNodes.length || (m.type === 'attributes' && m.target.tagName === 'A')) { scheduleRewrite(); return; } } }); function init() { rewriteAll(); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['href'], }); setInterval(() => rewriteAll(), 2000); } if (document.body) init(); else document.addEventListener('DOMContentLoaded', init); ['pushState', 'replaceState'].forEach(method => { const original = history[method]; history[method] = function(state, title, url) { if (url) { const target = getNestedPath(new URL(url, location.origin).href); if (target) { location.href = target; return; } } const ret = original.apply(this, arguments); scheduleRewrite(); return ret; }; }); window.addEventListener('popstate', function() { const target = getNestedPath(location.href); if (target) location.replace(target); else scheduleRewrite(); }); })();

标签:纯水