// ==UserScript==
// @name Floating Page Scroll Assistant
// @name:zh-CN 页面滚动助手
// @name:zh-TW 頁面滾動助手
// @namespace http://tampermonkey.net/
// @version 1.1.01
// @description A set of floating buttons on the screen that quickly scroll to the top and bottom of the page, and scroll up/down one page.
// @description:zh-CN 在屏幕上显示一组浮动按钮,帮助用户快速滚动到页面顶部或底部,并支持向上/向下滚动一页的功能。
// @description:zh-TW 在螢幕上顯示一組浮動按鈕,幫助用戶快速滾動到頁面頂部或底部,並支援向上/向下滾動一頁的功能。
// @author Kamiya Minoru
// @match *://*/*
// @exclude *://www.google.com/*
// @exclude *://www.google.com.tw/*
// @exclude *://www.google.co.jp/*
// @exclude https://www.bilibili.com/
// @exclude https://*.microsoft/*
// @exclude https://gemini.google.com/*
// @exclude https://chatgpt.com/
// @exclude https://claude.ai/*
// @exclude https://www.perplexity.ai/*
// @exclude https://chat.deepseek.com/*
// @exclude https://www.twitch.tv/
// @noframes
// @grant none
// @license MIT
// @downloadURL https://update.greasyfork.icu/scripts/527645/Floating%20Page%20Scroll%20Assistant.user.js
// @updateURL https://update.greasyfork.icu/scripts/527645/Floating%20Page%20Scroll%20Assistant.meta.js
// ==/UserScript==
(function() {
'use strict';
// Create a Trusted Types policy
const escapeHTMLPolicy = trustedTypes.createPolicy('myEscapePolicy', {
createHTML: (string) => string
});
// Create a container for the buttons
var container = document.createElement('div');
container.style.position = 'fixed';
container.style.right = '10px';
container.style.top = '185px';
container.style.transform = 'translateY(-50%)';
container.style.zIndex = '9999999';
document.body.appendChild(container);
// Function to create a button
function createButton(innerHTML, onClick, tooltip) {
var button = document.createElement('div');
button.innerHTML = escapeHTMLPolicy.createHTML(innerHTML); // 使用 TrustedHTML
button.style.width = '30px';
button.style.height = '30px';
button.style.cursor = 'pointer';
button.style.backgroundColor = 'transparent';
button.style.color = 'grey';
button.style.textAlign = 'center';
button.style.fontSize = '24px';
button.style.borderRadius = '50%';
button.style.userSelect = 'none';
button.style.marginBottom = '8px';
button.style.opacity = tooltip === 'Close' || tooltip === 'drag to Move' ? '0.3' : '0.4';
button.style.transition = 'all 0.3s';
button.style.display = 'flex';
button.style.alignItems = 'center';
button.style.justifyContent = 'center';
button.style.border = '1px solid grey';
button.title = tooltip;
button.addEventListener('click', onClick);
button.addEventListener('mouseover', function() {
button.style.opacity = '1';
button.style.filter = 'drop-shadow(0 0 1px grey)';
button.style.color = '#FFF';
if (tooltip === 'Close') {
button.querySelectorAll('path').forEach(path => {
path.style.stroke = 'red';
path.style.fill = 'red';
});
}
});
button.addEventListener('mouseout', function() {
button.style.opacity = tooltip === 'Close' || tooltip === 'drag to Move' ? '0.3' : '0.4';
button.style.filter = 'drop-shadow(0 0 0 grey)';
button.style.color = 'grey';
if (tooltip === 'Close') {
button.querySelectorAll('path').forEach(path => {
path.style.stroke = '#3276c3';
path.style.fill = '#3276c3';
});
}
});
return button;
}
// Create the buttons
var topButton = createButton('', function() {
window.scrollTo({ top: 0, behavior: 'instant' });
}, "Scroll to Top");
var pageUpButton = createButton('', function() {
window.scrollBy({ top: -window.innerHeight, behavior: 'instant' });
}, "Page Up");
var pageDownButton = createButton('', function() {
window.scrollBy({ top: window.innerHeight, behavior: 'instant' });
}, "Page Down");
var bottomButton = createButton('', function() {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'instant' });
}, "Scroll to Bottom");
var closeButton = createButton('', function() {
container.style.display = 'none';
}, "Close");
// Create the drag button
var dragButton = createButton('', function() {}, "drag to Move");
dragButton.style.cursor = 'grab';
dragButton.addEventListener('mousedown', function(e) {
dragButton.style.cursor = 'grabbing';
var initialX = e.clientX;
var initialY = e.clientY;
var initialLeft = container.offsetLeft;
var initialTop = container.offsetTop;
function moveAt(pageX, pageY) {
container.style.left = initialLeft + (pageX - initialX) + 'px';
container.style.top = initialTop + (pageY - initialY) + 'px';
}
function onMouseMove(event) {
moveAt(event.clientX, event.clientY);
}
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', function() {
dragButton.style.cursor = 'grab';
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', arguments.callee);
});
});
dragButton.ondragstart = function() {
return false;
};
// Append buttons to the container
container.appendChild(topButton);
container.appendChild(pageUpButton);
container.appendChild(pageDownButton);
container.appendChild(bottomButton);
container.appendChild(closeButton);
container.appendChild(dragButton);
})();