您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Smooth scrolling on pages using javascript
当前为
- // ==UserScript==
- // @name Smoothscroll
- // @author Creec Winceptor
- // @description Smooth scrolling on pages using javascript
- // @namespace https://greasyfork.org/users/3167
- // @include *
- // @version 6
- // ==/UserScript==
- var Smoothscroll = {};
- //dev
- Smoothscroll.Debug = false;
- Smoothscroll.Refreshrate = 60;
- //settings
- Smoothscroll.Smoothness = 0.5;
- Smoothscroll.Acceleration = 0.5;
- //scrolling and animation
- function Timeout(element, newtimeout)
- {
- if (newtimeout!=undefined)
- {
- var oldtimeout = element.ScrollTimeout;
- if (oldtimeout!=undefined)
- {
- clearTimeout(oldtimeout);
- }
- element.ScrollTimeout = newtimeout;
- return newtimeout;
- }
- else
- {
- var oldtimeout = element.ScrollTimeout;
- if (oldtimeout!=undefined)
- {
- return oldtimeout;
- }
- return null;
- }
- }
- function ScrollSubpixels(element, newvalue)
- {
- if (newvalue!=undefined)
- {
- element.scrollsubpixels = newvalue;
- return newvalue;
- }
- else
- {
- var olddelta = element.scrollsubpixels;
- if (olddelta!=undefined)
- {
- return olddelta;
- }
- return 0;
- }
- }
- function ScrollPixels(element, newvalue)
- {
- if (newvalue!=undefined)
- {
- element.scrollpixels = newvalue;
- ScrollSubpixels(element, 0);
- return newvalue;
- }
- else
- {
- var olddelta = element.scrollpixels;
- if (olddelta!=undefined)
- {
- return olddelta;
- }
- return 0;
- }
- }
- function AnimateScroll(target) {
- var updaterate = Math.floor(1000/(Smoothscroll.Refreshrate));
- var scrollsubpixels = ScrollSubpixels(target);
- var scrollpixels = ScrollPixels(target);
- var scrolldirection = 0;
- if (scrollpixels>0) {
- scrolldirection = 1;
- }
- if (scrollpixels<0) {
- scrolldirection = -1;
- }
- var scrollratio = 1-Math.pow( Smoothscroll.Refreshrate, -1/(Smoothscroll.Refreshrate*Smoothscroll.Smoothness));
- var scrollrate = scrollpixels*scrollratio;
- if (Math.abs(scrollpixels)>1) {
- var fullscrolls = Math.floor(Math.abs(scrollrate))*scrolldirection;
- var scrollsubpixelsadded = scrollrate - fullscrolls;
- var additionalscrolls = Math.floor(Math.abs(scrollsubpixels + scrollsubpixelsadded))*scrolldirection;
- var scrollsubpixelsleft = scrollsubpixels + scrollsubpixelsadded - additionalscrolls;
- ScrollPixels(target, scrollpixels-fullscrolls-additionalscrolls);
- ScrollSubpixels(target, scrollsubpixelsleft);
- target.scrollTop += fullscrolls + additionalscrolls;
- Timeout(target, setTimeout(function() {
- AnimateScroll(target);
- }, updaterate));
- } else
- {
- ScrollPixels(target, 0);
- }
- }
- Smoothscroll.Stop = function(target) {
- if (target) {
- ScrollPixels(target, null);
- Timeout(target, null);
- }
- }
- Smoothscroll.Start = function(target, scrollamount) {
- if (target) {
- var scrollpixels = ScrollPixels(target);
- ScrollPixels(target, scrollamount);
- AnimateScroll(target);
- }
- }
- if (typeof module !== 'undefined') {
- module.exports = Smoothscroll;
- }
- //scroll target detection
- function IsScrollable(element, dir)
- {
- //TODO: problem with webkit, body not scrollable?
- if (element==document.body) {
- return false;
- }
- if (dir>0)
- {
- if (Smoothscroll.Debug) {
- console.log("element.offsetHeight: " + element.offsetHeight);
- console.log("element.clientHeight: " + element.clientHeight);
- console.log("element.scrollTop: " + element.scrollTop);
- console.log("element.scrollHeight: " + element.scrollHeight);
- }
- return element.scrollTop+element.clientHeight<element.scrollHeight;
- }
- if (dir<0)
- {
- return element.scrollTop>0;
- }
- return true;
- }
- //scroll target detection backup
- function IsScrollable0(element, dir)
- {
- //TODO: problem with webkit, body not scrollable?
- if (element==document.body) {
- return false;
- }
- var checkradius = 3; //pixels to try scrolling
- if (dir>0)
- {
- dir = checkradius;
- }
- if (dir<0)
- {
- dir = -checkradius;
- }
- var originalscroll = element.scrollTop;
- var testscroll = Math.round(originalscroll + dir);
- element.scrollTop = testscroll;
- var scrollable = Math.round(element.scrollTop)==testscroll;
- element.scrollTop = originalscroll;
- return scrollable;
- }
- function HasScrollbars(element)
- {
- if (element==window || element==document) {
- return false;
- }
- //return (document.documentElement.scrollHeight !== document.documentElement.clientHeight);
- // Get the computed style of the body element
- var cStyle = element.currentStyle || window.getComputedStyle(element, "");
- // Check the overflow and overflowY properties for "auto" and "visible" values
- var scrollbar0 = element==document.body || element==document.documentElement;
- var scrollbar1 = cStyle.overflow != "hidden" && cStyle.overflowY != "hidden";
- var scrollbar2 = cStyle.overflowY == "scroll" || cStyle.overflowY == "auto";
- var scrollbar3 = cStyle.maxHeight<cStyle.height;
- //body or html always have scrollbars
- var scrollbar4 = cStyle.overflow != "hidden" && cStyle.overflowY != "hidden";
- return scrollbar0 || (scrollbar1 || scrollbar2) && scrollbar3;
- }
- function GetTarget(e) {
- var direction = e.deltaY;
- var nodes = e.path;
- if (Smoothscroll.Debug) {
- console.log("nodes: ");
- console.log(nodes);
- console.log("target: ");
- }
- for (var i=0; i<(nodes.length); i++) {
- var node = nodes[i];
- if (Smoothscroll.Debug) {
- console.log(node);
- }
- var scrollable_check = IsScrollable(node, direction);
- if (Smoothscroll.Debug) {
- console.log("scrollable_check: " + scrollable_check);
- }
- var scrollbar_check = HasScrollbars(node);
- if (Smoothscroll.Debug) {
- console.log("scrollbar_check: " + scrollbar_check);
- }
- if (scrollable_check && scrollbar_check)
- {
- if (Smoothscroll.Debug) {
- console.log("true");
- }
- return node;
- }
- }
- if (Smoothscroll.Debug) {
- console.log("false");
- }
- return null;
- }
- //mouse event scroll handlers
- function StopScroll(e) {
- var nodes = e.path;
- for (var i=0; i<nodes.length; i++) {
- var node = nodes[i];
- Smoothscroll.Stop(node);
- }
- }
- function StartScroll(e, target) {
- if (e.defaultPrevented)
- {
- return true;
- }
- else
- {
- var direction = e.deltaY;
- var scrollpixels = ScrollPixels(target);
- var accelerationratio = Math.sqrt(Math.abs(scrollpixels/direction*Smoothscroll.Acceleration));
- var acceleration = Math.round(direction*accelerationratio);
- Smoothscroll.Start(target, scrollpixels + direction + acceleration);
- e.preventDefault();
- }
- }
- //mouse event call handlers
- function WheelEvent(e) {
- var target = GetTarget(e);
- if (target) {
- StartScroll(e, target);
- }
- }
- function ClickEvent(e) {
- StopScroll(e);
- }
- //init function
- function Init()
- {
- if (window.top != window.self) {
- //console.log("Smoothscroll: ignoring iframe");
- return null;
- }
- if (window.Smoothscroll && window.Smoothscroll.Loaded) {
- //console.log("Smoothscroll: already loaded");
- return null;
- }
- document.documentElement.addEventListener("wheel", function(e){
- WheelEvent(e);
- if (Smoothscroll.Debug) {
- console.log(e);
- }
- });
- document.documentElement.addEventListener("mousedown", function(e){
- ClickEvent(e);
- if (Smoothscroll.Debug) {
- console.log(e);
- }
- });
- window.Smoothscroll = Smoothscroll;
- window.Smoothscroll.Loaded = true;
- console.log("Smoothscroll: loaded");
- }
- Init();