您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Scroll the page while holding chosen mouse button anywhere on the website
- // ==UserScript==
- // @name Scroll by mouse drag
- // @namespace FawayTT
- // @description Scroll the page while holding chosen mouse button anywhere on the website
- // @match *://*/*
- // @version 1.2
- // @author FawayTT
- // @license MIT
- // @homepage https://github.com/FawayTT/userscripts
- // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_registerMenuCommand
- // @grant GM_openInTab
- // ==/UserScript==
- GM_registerMenuCommand('Settings', opencfg);
- const configcss = `height: 40rem;
- width: 35rem;
- border-radius: 10px;
- z-index: 9999999;
- position: fixed;
- `;
- const defaults = {
- touchArea: `width: 100%;
- height: 100%;
- position: fixed;
- left: 50%;
- top: 0;
- pointer-events: none;
- transform: translateX(-50%);`,
- };
- let gmc = new GM_config({
- id: 'config',
- title: 'Scroll by mouse drag settings',
- fields: {
- scrollButton: {
- section: ['Behavior'],
- label: 'Scroll button',
- labelPos: 'left',
- type: 'select',
- default: 'Left', // Default value for Blue
- options: ['Left', 'Right', 'MiddleClick'],
- },
- touchArea: {
- label: 'Touchpad zone position custom CSS (by default, its invisible and centered in the middle of the page)',
- labelPos: 'left',
- type: 'textarea',
- default: defaults.touchArea,
- },
- msClick: {
- label: 'Number of ms before scroll starts',
- labelPos: 'left',
- type: 'number',
- default: 100,
- },
- textSelectable: {
- label: 'Turn off when selecting text',
- labelPos: 'right',
- type: 'checkbox',
- default: true,
- },
- scrollSpeed: {
- section: ['Speed'],
- label: 'Speed of scroll',
- labelPos: 'left',
- type: 'number',
- default: 1.5,
- },
- blacklistedSites: {
- section: ['Sites'],
- label: 'Blacklisted sites (separated by comma)',
- labelPos: 'right',
- type: 'text',
- default: '',
- },
- whitelistEnabled: {
- label: 'Whitelist enabled',
- labelPos: 'right',
- type: 'checkbox',
- default: false,
- },
- whitelistedSites: {
- label: 'Whitelisted sites (separated by comma)',
- labelPos: 'right',
- type: 'text',
- default: '',
- },
- url: {
- section: ['Support'],
- label: 'https://github.com/FawayTT/userscripts',
- type: 'button',
- click: () => {
- GM_openInTab('https://github.com/FawayTT/userscripts');
- },
- },
- },
- events: {
- save: function () {
- gmc.close();
- },
- init: onInit,
- },
- });
- const scrollDiv = document.createElement('div');
- let animationDuration = 100;
- let isMouseDown = false;
- let startY = 0;
- let startX = 0;
- let startTimeout;
- let distance = 0;
- let isScrolling;
- let clicks = 0;
- let textSelectable;
- let button;
- let msClick;
- let scrollSpeed = 1.5;
- const animateScroll = (distance) => {
- const startTime = performance.now();
- const startScrollY = window.scrollY;
- let extraScroll = true;
- const scroll = (timestamp) => {
- const elapsedTime = timestamp - startTime;
- const progress = Math.min(elapsedTime / animationDuration, 1);
- const scrollAmount = startScrollY + distance * progress;
- if (window.scrollY < 50 && distance < 0) {
- return;
- }
- window.scrollTo(0, Math.abs(scrollAmount));
- if (progress < 1) {
- requestAnimationFrame(scroll);
- } else {
- isScrolling = false;
- if (extraScroll) {
- extraScroll = false;
- window.scrollBy({ top: distance * 0.5, behavior: 'smooth' });
- }
- }
- };
- requestAnimationFrame(scroll);
- };
- function onInit() {
- const whitelistEnabled = gmc.get('whitelistEnabled');
- const blacklistedSites = gmc.get('blacklistedSites');
- const whitelistedSites = gmc.get('whitelistedSites');
- button = gmc.get('scrollButton');
- textSelectable = gmc.get('textSelectable');
- msClick = gmc.get('msClick');
- scrollSpeed = gmc.get('scrollSpeed');
- switch (button) {
- case 'Left':
- button = 0;
- break;
- case 'Right':
- button = 2;
- break;
- default:
- button = 1;
- break;
- }
- if (whitelistEnabled) {
- if (whitelistedSites.length > 0) {
- const whitelistedSitesArray = whitelistedSites.split(',').map((site) => site.trim());
- const currentSite = window.location.href;
- if (whitelistedSitesArray.includes(currentSite)) init();
- }
- } else {
- if (blacklistedSites.length > 0) {
- const blacklistedSitesArray = blacklistedSites.split(',').map((site) => site.trim());
- const currentSite = window.location.href;
- if (!blacklistedSitesArray.includes(currentSite)) init();
- } else init();
- }
- }
- function opencfg() {
- gmc.open();
- config.style = configcss;
- }
- const pauseEvent = (e) => {
- if (e.stopPropagation) e.stopPropagation();
- if (e.preventDefault) e.preventDefault();
- e.cancelBubble = true;
- e.returnValue = false;
- return false;
- };
- const getScrollValue = (value) => {
- return value * scrollSpeed;
- };
- const reset = () => {
- if (isMouseDown) {
- document.body.style.cursor = null;
- }
- isMouseDown = false;
- isScrolling = false;
- clearTimeout(startTimeout);
- };
- const checkScroll = (e) => {
- const rect = scrollDiv.getBoundingClientRect();
- const scrollDivX = rect.left + window.scrollX;
- clearTimeout(startTimeout);
- if (e.button === button && e.pageX >= scrollDivX && e.pageX <= scrollDivX + rect.width) {
- if (button !== 0) e.preventDefault();
- startTimeout = setTimeout(() => {
- isMouseDown = true;
- startY = e.clientY;
- startX = e.clientX;
- document.body.style.setProperty('cursor', 'grabbing');
- }, msClick);
- }
- };
- const scroll = (e) => {
- if (isMouseDown && e.buttons & (1 === 1)) pauseEvent(e);
- if (isScrolling || !isMouseDown) return;
- if (window.getSelection().toString().length > 0 || (textSelectable && Math.abs(startX - e.clientX) > 50)) {
- reset();
- return;
- }
- distance = -(startY - e.clientY);
- isScrolling = true;
- distance = getScrollValue(distance);
- animateScroll(distance);
- };
- function init() {
- scrollDiv.style.cssText = gmc.get('touchArea');
- document.body.appendChild(scrollDiv);
- document.addEventListener(
- 'contextmenu',
- (e) => {
- if (button === 2 && !doubleClick) e.preventDefault();
- },
- false
- );
- document.addEventListener('mousedown', checkScroll);
- document.addEventListener('mouseup', reset);
- document.addEventListener('mousemove', scroll);
- }