您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add clickable fragment links to all headings
// ==UserScript== // @name Heading Fragment Linker // @namespace http://tampermonkey.net/ // @version 2.0 // @description Add clickable fragment links to all headings // @author maanimis // @match *://*/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // Function to create a URL-safe ID from heading text function createIdFromText(text) { return text .toLowerCase() .trim() .replace(/[^a-z0-9\s-]/g, '') // Remove special characters .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/-+/g, '-') // Replace multiple hyphens with single .replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens } // Function to make headings clickable function makeHeadingsClickable() { const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); headings.forEach((heading, index) => { // Skip if heading already has an ID if (heading.id) return; // Create ID from heading text or use fallback let id = createIdFromText(heading.textContent); // Ensure ID is unique if (!id || document.getElementById(id)) { id = `heading-${index + 1}`; } // Assign the ID heading.id = id; // Add click event to update URL heading.style.cursor = 'pointer'; heading.addEventListener('click', function(e) { // Only update URL if it's different from current hash if (window.location.hash !== `#${this.id}`) { history.replaceState(null, null, `#${this.id}`); // Scroll to the element after updating URL this.scrollIntoView({ behavior: 'smooth' }); } }); }); } // Function to scroll to heading if URL contains hash (only on initial load) function scrollToHashOnLoad() { if (window.location.hash) { // Wait a bit for content to load setTimeout(() => { const target = document.querySelector(window.location.hash); if (target) { target.scrollIntoView({ behavior: 'smooth' }); } }, 100); } } // Run immediately makeHeadingsClickable(); // Only scroll to hash on initial page load, not on subsequent hash changes if (!window.location.hash || !window.sessionStorage.getItem('hashScrolled')) { scrollToHashOnLoad(); window.sessionStorage.setItem('hashScrolled', 'true'); } // Re-run when new content is added (for SPAs) const observer = new MutationObserver(() => { makeHeadingsClickable(); }); observer.observe(document.body, { childList: true, subtree: true }); })();