您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
默认取第一个table of contents,请知晓。支持悬浮目录和悬浮Heading!
// ==UserScript== // @name Notion TOC Floating | 悬浮目录 | 悬浮Heading // @namespace https://github.com/gefangshuai/tampermokey-scripts // @version 0.1.8 // @description 默认取第一个table of contents,请知晓。支持悬浮目录和悬浮Heading! // @author Timothy.Ge // @include *://*.notion.*/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant GM_addStyle // @note 21-08-11 0.1.8 兼容新站点 // @note 21-08-11 0.1.7 兼容新站点 // @note 21-08-11 0.1.6 兼容新站点 // @note 21-06-02 0.1.5 优化Sticky Heading逻辑,当页面包含多列的时候,禁用悬浮 // @note 21-06-02 0.1.4 优化了悬浮逻辑,增加了table_of_contents激活效果 // @note 21-06-02 0.1.3 新增了对h1、h2、h3的悬浮支持 // @note 21-05-25 0.1.2 更新说明 // @note 21-05-25 0.1.1 解决了更换文章失效的问题 // @note 21-05-25 0.1.0 第一个测试版本 // ==/UserScript== GM_addStyle(` div.notion-frame:not(.prevent-heading-sticky) div.notion-page-content .notion-header-block, div.notion-frame:not(.prevent-heading-sticky) div.notion-page-content .notion-sub_header-block { position: sticky !important; top: 0; background: #fff; z-index: 9999; } `); (function() { (function(history) { 'use strict'; // Your code here... var preventHeadingSticky = function() { document.querySelector('div.notion-frame').classList.add('prevent-heading-sticky'); }; var doSomething = function() { // float TOC var scroller = document.querySelector('div.notion-frame .notion-scroller'); if (scroller) { if (window.$$_scrollWatchFun) { scroller.removeEventListener('scroll', window.$$_scrollWatchFun); } else { window.$$_scrollWatchFun = function(e) { // float table_of_contents var tableContents = document.querySelector('.notion-table_of_contents-block'); if (tableContents) { preventHeadingSticky(); var rect = tableContents.getBoundingClientRect(); var dom = tableContents.firstChild; if (dom) { if (rect.top <= 60) { dom.style.position = 'fixed'; dom.style.top = '60px'; dom.style.width = rect.width + 'px'; } else { dom.style.position = null; dom.style.top = null; } } } else if (document.querySelectorAll('.notion-column-block').length > 0) { preventHeadingSticky(); } else { document.querySelector('div.notion-frame').classList.remove('prevent-heading-sticky'); } if (tableContents) { // add hover style to table_of_contents var headers = document.querySelectorAll('.notion-header-block, .notion-sub_header-block, .notion-sub_sub_header-block'); var current; var currentIndex = -1; if (headers && headers.length > 0) { for (var i = 0; i < headers.length; i++) { if (headers[i].getBoundingClientRect().top < 45) { current = headers[i].textContent; currentIndex = i; } } } var allA = tableContents.querySelectorAll('a'); if (allA && allA.length > 0) { if (current) { if (allA.length > 0) { for (let i = 0; i < allA.length; i++) { if (i === currentIndex) { allA[i].style.background = 'rgba(55, 53, 47, 0.08)'; } else { allA[i].style.background = 'unset'; } } } } else { for (let i = 0; i < allA.length; i++) { allA[i].style.background = 'unset'; } } } } }; } scroller.addEventListener('scroll', window.$$_scrollWatchFun); } }; doSomething(); var pushState = history.pushState; history.pushState = function(state) { if (typeof history.onpushstate == 'function') { history.onpushstate({ state: state }); } setTimeout(function() { doSomething(); }, 3000); return pushState.apply(history, arguments); }; })(window.history); })();