默认取第一个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);
})();