您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Smooth scrolling on pages using javascript and jquery
当前为
// ==UserScript== // @name Smoothscroll // @include http* // @author Creec Winceptor // @description Smooth scrolling on pages using javascript and jquery // @namespace https://greasyfork.org/users/3167 // @run-at document-load // @grant none // @require https://code.jquery.com/jquery-2.2.3.js // @version 0.0.1.20160524203323 // ==/UserScript== this.$ = this.jQuery = jQuery.noConflict(true); //SETTINGS HERE //Smoothness factor value (how strong the smoothing effect is) //values: 1-(infinite) (default = 50) var smoothness = 30; //Scroll sensitivity //values: anything? (default 1.00) var sensitivity = 1.00; //Acceleration sensitivity //values: anything? (default 1.00) var acceleration = 1.00; //Refreshrate setting //values: 30-144 (default = 60/72/120/144 = same as your monitor hz) var baserefreshrate = 60; //Alternative scrolling multiplier //values: true/false (try to set this to true if scrolling is too slow/doesn't work) var alternative_sesitivity_multiplier = false; var minimal_jquery_version = 200; var DEBUG = false; var WEBKIT = false; //CODE STARTS HERE if (window.top != window.self) //don't run on frames or iframes return; if (smoothness>100) { smoothness = 100; } if (baserefreshrate <= 30 || baserefreshrate>144) { baserefreshrate = 144; } refreshrate = baserefreshrate; var animationduration = Math.round(1000/refreshrate); //var relativeratio = Math.round(51-smoothness/2)/100; var relativeratio = Math.round(1/(1+smoothness)*100)/100; //var relativeratio = relativeratio; var lastLoop = new Date; //var lastrefreshrate = 0; function gameLoop() { var thisLoop = new Date; var refreshrate0 = 1000 / (thisLoop - lastLoop + 1); lastLoop = thisLoop; refreshrate = refreshrate + (refreshrate0-refreshrate)*0.01; refreshrate = Math.round(refreshrate); if (DEBUG) { console.log(refreshrate); } animationduration = Math.round(1000/(refreshrate)); //var relativeratio = Math.round(51-smoothness/2)/100; relativeratio = Math.round(1/(1+smoothness*refreshrate/baserefreshrate)*100)/100; } gameLoop(); function InitSmoothscroll() { var startposition = false; var targetposition = 0; var position = 0; var scrollfocus = ss$('body'); function hasScrollBarVisible(element) { //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 scrollbar1 = cStyle.overflow == "scroll" || cStyle.overflowY == "scroll"; var scrollbar2 = cStyle.overflow == "auto" || cStyle.overflowY == "auto"; var scrollbar = scrollbar1 || scrollbar2; return scrollbar; } function hasscrollbars(scrollfocus) { var hasvisiblescrollbars = hasScrollBarVisible(scrollfocus); var parentelement = ss$(scrollfocus).parent(); if ( ss$(parentelement)) { //if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea")) if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea") || ss$(parentelement).is("article") || ss$(parentelement).is("article")) { return true; } else { if (ss$(parentelement).hasClass( "yt-scrollbar" ) || ss$(scrollfocus).hasClass( "yt-scrollbar" )) { return true; } return hasvisiblescrollbars; } } else { //scrollfocus = ss$('body'); //maxposition = ss$(scrollfocus).height(); return hasvisiblescrollbars; } return false; } function UpdatePosition(element) { gameLoop(); var positiondelta = ss$(element)[0].getAttribute( "positiondelta" ); //var smoothdelta = Math.sqrt(positiondelta*positiondelta*relativeratio); var smoothdelta = Math.sqrt(positiondelta*positiondelta*relativeratio); if (positiondelta<0) { smoothdelta = smoothdelta*(-1); } //var relative = position - ss$(element).scrollTop(); //console.log("smoothdelta:" + smoothdelta); if (Math.abs( (positiondelta-smoothdelta)) <= 1 ) { ss$(element).stop(); ss$(element).animate({ scrollTop: '+=' + Math.round(positiondelta) }, animationduration, "linear", function() { ss$(element).attr( "positiondelta",0 ); ss$(element)[0].setAttribute( "positiondelta",0 ); if (DEBUG) { ss$(element).css( "border", "1px solid red" ); } }); } else { ss$(element).stop(); ss$(element).animate({ scrollTop: '+=' + Math.round(smoothdelta) }, animationduration, "linear", function() { ss$(element).attr( "positiondelta",positiondelta-smoothdelta ); ss$(element)[0].setAttribute("positiondelta",positiondelta-smoothdelta ); UpdatePosition(element); if (DEBUG) { ss$(element).css( "border", "1px solid red" ); } }); } } function MouseScroll (x,y,e) { scrollfocus = UpdateFocus(x,y); var positiondelta = 0; var lastscrolltop = 0; var parentelement = ss$(scrollfocus).parent(); if ( ss$(parentelement)) { if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea")) { //return true; } else { if ( ss$(parentelement).height() < ss$(scrollfocus).height()) { //maxposition = ss$(scrollfocus).height() - ss$(parentelement).height(); } else { if (ss$(scrollfocus).height()==0) { //scrollfocus = ss$('body'); //maxposition = ss$(scrollfocus).height(); } //scrollfocus = ss$('body'); //return MouseScroll (event); //return true; } } } else { //scrollfocus = ss$('html'); //maxposition = ss$(scrollfocus).height(); } var rolled = y; //console.log("rolled: " + rolled); //if (ss$(scrollfocus).data("positiondelta" )==undefined) //$embellishment.data("embellishmentid",1) var lastscrolltop = ss$(scrollfocus).scrollTop(); ss$(scrollfocus).scrollTop(lastscrolltop+rolled); if (ss$(scrollfocus).scrollTop()==lastscrolltop) { if (!ss$(scrollfocus).is("html")) { focus = parentelement; //focus = UpdateFocus(event); //return MouseScroll (event); //console.log("false"); //return false; } else { //console.log("true"); //return false; } } else { e.preventDefault(); } ss$(scrollfocus).scrollTop(lastscrolltop); //console.log(scrollfocus); if (ss$(scrollfocus)[0].getAttribute("positiondelta")==undefined) { positiondelta = 0; //console.log("positiondelta: undefined"); } else { positiondelta = ss$(scrollfocus)[0].getAttribute("positiondelta"); //console.log("positiondelta: " + positiondelta); } positiondelta = positiondelta*1; var direction = rolled/Math.abs(rolled); //var positiondeltadelta = rolled*sensitivity + Math.sqrt(Math.abs(positiondelta/rolled))*acceleration*rolled; //var positiondeltadelta = rolled*(sensitivity+Math.sqrt(Math.abs(positiondelta))*acceleration); // var positiondeltadelta = Math.round(rolled*sensitivity + Math.sqrt(Math.abs(positiondelta-rolled*sensitivity))*acceleration*rolled*0.03/sensitivity); positiondelta = positiondelta + positiondeltadelta; ss$(scrollfocus)[0].setAttribute("positiondelta",positiondelta ); UpdatePosition(ss$(scrollfocus)); //element.innerHTML = ""; //console.log("pos:" + position); //event.preventDefault(); return true; } function canscroll(element, dir) { var scrollable = ss$(element); var lastscrolltop = ss$(scrollable).scrollTop(); ss$(scrollable).scrollTop(lastscrolltop+dir); if (ss$(scrollable).scrollTop()==lastscrolltop) { ss$(scrollable).scrollTop(lastscrolltop); return false; } else { ss$(scrollable).scrollTop(lastscrolltop); return true; } } function UpdateFocus(x,y) { /*var dir = 0; if ('wheelDelta' in event) { dir = event.wheelDelta; } else { // Firefox // The measurement units of the detail and wheelDelta properties are different. dir = event.detail*(-120); }*/ var dir = y; //console.log(dir); //dir = dir*(-1); // var nodelist = document.querySelectorAll( ":hover" ); ss$(nodelist).stop(); //console.log(nodelist); if (WEBKIT) { scrollfocus = ss$('body'); } else { scrollfocus = ss$('html'); } for (var i = nodelist.length-1; i >= 0; i--) { //var parent = nodelist[i-1]; var newfocus = nodelist[i]; if (DEBUG) { ss$(newfocus).css( "border", "1px solid blue" ); //var debugtimer = setTimeout(function(){ ss$(newfocus).css( "border", "0px solid white" ); }, 1000); } //if (ss$(newfocus).hasScrollBar3() && hasScrollBarVisible(newfocus) && canscroll(newfocus, dir) && hasscrollbars(newfocus)) if (canscroll(newfocus, dir) && hasscrollbars(newfocus)) { scrollfocus = ss$(newfocus); return newfocus; } } return scrollfocus; } ss$('body').bind({ /* mousewheel: function(e) { if (DEBUG) { console.log(scrollfocus); } console.log("scrolling"); MouseScroll(e.originalEvent); }, */ mousedown: function(e) { if (DEBUG) { console.log(scrollfocus); } if (scrollfocus) { ss$(scrollfocus)[0].setAttribute( "positiondelta",0 ); ss$(scrollfocus).stop(); } //scrollfocus = UpdateFocus(e.originalEvent); //console.log("click"); } }); //Init(window); (function(window,document) { var prefix = "", _addEventListener, onwheel, support; // detect event model if ( window.addEventListener ) { _addEventListener = "addEventListener"; } else { _addEventListener = "attachEvent"; prefix = "on"; } // detect available wheel event support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel" document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel" "DOMMouseScroll"; // let's assume that remaining browsers are older Firefox window.addWheelListener = function( elem, callback, useCapture ) { _addWheelListener( elem, support, callback, useCapture ); // handle MozMousePixelScroll in older Firefox if( support == "DOMMouseScroll" ) { _addWheelListener( elem, "MozMousePixelScroll", callback, useCapture ); } }; function _addWheelListener( elem, eventName, callback, useCapture ) { elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) { !originalEvent && ( originalEvent = window.event ); // create a normalized event object var event = { // keep a ref to the original event object originalEvent: originalEvent, target: originalEvent.target || originalEvent.srcElement, type: "wheel", deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1, deltaX: 0, deltaZ: 0, preventDefault: function() { originalEvent.preventDefault ? originalEvent.preventDefault() : originalEvent.returnValue = false; } }; // calculate deltaY (and deltaX) according to the event if ( support == "mousewheel" ) { event.deltaY = - 1/40 * originalEvent.wheelDelta; // Webkit also support wheelDeltaX originalEvent.wheelDeltaX && ( event.deltaX = - 1/40 * originalEvent.wheelDeltaX ); } else { event.deltaY = originalEvent.detail; } // it's time to fire the callback return callback( event ); }, useCapture || false ); } })(window,document); addWheelListener( window, function( e ) { var mul = 1; if (!WEBKIT) mul = 40; if (alternative_sesitivity_multiplier) mul = 40; //console.log( e.deltaY ); MouseScroll(e.deltaX*mul,e.deltaY*mul, e); }); var oldpos = ss$('body').scrollTop(); ss$('body').scrollTop(1); var iswebkit = ss$('body').scrollTop()>0; ss$('body').scrollTop(oldpos); WEBKIT = iswebkit; console.log("Smoothscroll initiated!"); } var JQUERY = false; var OWNJQUERY = false; var OLDJQUERY = false; //max retries var r_max = 10; var r_count = 0; function Init(LEGACYWORKAROUND) { //if (typeof jQuery == 'function') { //if (typeof jQuery == 'undefined' || typeof $ == 'undefined' ) JQUERY = true; if (typeof $ == 'undefined' ) { JQUERY = false; } OWNJQUERY = true; if (typeof ss$ == 'undefined' ) { OWNJQUERY = false; } if (!OWNJQUERY){ if (JQUERY) { var versiontable = $.fn.jquery.split('.'); var version = 0; for (var i = versiontable.length-1; i >= 0; i--) { var power = versiontable.length-i; version += Math.pow(10,power-1)*versiontable[i]; } if (version<=minimal_jquery_version && LEGACYWORKAROUND) { console.log("Page jQuery OLD! Version: " + version); if (typeof old$ == 'undefined') { console.log("Saving old jQuery..."); old$ = $; oldjQuery = jQuery; OLDJQUERY = true; } } else { ss$ = $; OWNJQUERY = true; } } else { console.log("Page jQuery Missing!"); } } if (!OWNJQUERY && LEGACYWORKAROUND) { console.log("Loading new jQuery..."); //this.$ = this.jQuery = jQuery.noConflict(true); //var $ = jQuery.noConflict(); //this.$ = this.jQuery = jQuery.noConflict(true); var filename = "https://code.jquery.com/jquery-2.2.3.js"; var fileref = document.createElement('script'); fileref.setAttribute("type","text/javascript"); fileref.setAttribute("src", filename); if (typeof fileref!="undefined") { var scriptparent = document.getElementsByTagName("head")[0]; if (typeof scriptparent=="undefined") { var scriptparent = document.createElement('head'); document.getElementsByTagName("html")[0].appendChild(scriptparent); } scriptparent.appendChild(fileref); } if (r_count<r_max) { setTimeout(Init, 300); return 0; } else { console.log("Failed to load smoothscroll!"); } r_count++; } if (OWNJQUERY) { var versiontable = ss$.fn.jquery.split('.'); var version = 0; for (var i = versiontable.length-1; i >= 0; i--) { var power = versiontable.length-i; version += Math.pow(10,power-1)*versiontable[i]; } console.log("Script jQuery OK! Version: " + version); InitSmoothscroll(); } if (OLDJQUERY && LEGACYWORKAROUND) { console.log("Restoring old jQuery..."); $ = old$; jQuery = oldjQuery; var versiontable = $.fn.jquery.split('.'); var version = 0; for (var i = versiontable.length-1; i >= 0; i--) { var power = versiontable.length-i; version += Math.pow(10,power-1)*versiontable[i]; } console.log("Page jQuery OK! Version: " + version); } console.log("Finished loading smoothscroll!"); } console.log("Loading smoothscroll..."); Init(true); //InitSmoothscroll();