Smoothscroll

Smooth scrolling on pages using javascript and jquery

目前为 2015-01-04 提交的版本。查看 最新版本

// ==UserScript==
// @name Smoothscroll
// @include     http*
// @author       Creec Winceptor
// @description  Smooth scrolling on pages using javascript and jquery
// @namespace https://greasyfork.org/users/3167
// @require       http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @grant       GM_addStyle
// @version 0.0.1.20150104221223
// ==/UserScript==
/*- The @grant directive is needed to work around a design change introduced in GM 1.0,
    It restores the sandbox.
*/



//SETTINGS HERE

//Refreshrate setting (affects rate at which scrolling is refreshed) 
//values: 1-1000 (just leave it 100)
var refreshrate = 100;

//Smoothness value (how strong the smoothing effect is)
//values: 1-100
var smoothness = 67;



//CODE STARTS HERE
this.$ = this.jQuery = jQuery.noConflict(true);

if (window.top != window.self)  //don't run on frames or iframes
    return;

var animationduration = Math.round(1000/refreshrate);
var relativeratio = Math.round(101-smoothness)/100;
var relativeratio = relativeratio*relativeratio;

var startposition = false;
var targetposition = 0;
var position = 0;

var focus = $('body');


(function($) {
    $.fn.has_scrollbar = function() {
        var divnode = this.get(0);
        if(divnode.scrollHeight > divnode.clientHeight)
            return true;
    }
})(jQuery);


function UpdatePosition(element)
{
	var positiondelta = $(element)[0].getAttribute( "positiondelta" );
	var smoothdelta = positiondelta*relativeratio;
	
	
	//var relative = position - $(element).scrollTop();
	//$(element).css( "border", "3px solid red" );
	//console.log("relative:" + relative);
	if (Math.abs( (positiondelta-smoothdelta)/2) <= 1 )
	{
		$(element)[0].setAttribute( "positiondelta",0 );
		$(element).stop();
		$(element).animate({
			scrollTop: '+=' + Math.round(positiondelta)
		}, animationduration*2, "linear");
	}
	else
	{
		$(element).attr( "positiondelta",positiondelta-smoothdelta );
		$(element)[0].setAttribute("positiondelta",positiondelta-smoothdelta );
		$(element).stop();
		$(element).animate({
				scrollTop: '+=' + Math.round(smoothdelta)
			}, animationduration, "linear", function() {UpdatePosition(element);}
		);
	}
}


function getscrollable(element)
{
	var parentelement = $(element).parent();
	if ( $(parentelement))
	{
		if ( $(parentelement).height() < $(element).height())
			{
				return $(element);
			}
		else
			{
				return getscrollable( $(element));
			}
		
	}
	else
	{
		return $('body');
	}
}

 function MouseScroll (event) {
		
	 var positiondelta = 0;
	 var maxposition = $(focus).height();
	 if ($(focus).is("textarea"))
		 {
			 return false;
		 }
	 else
		 { 
			 var parentelement = $(focus).parent();
			if ( $(parentelement))
			{
				if ($(parentelement).is("textarea") || $(focus).is("textarea"))
				 {
					 return false;
				 }
				if ( $(parentelement).height() < $(focus).height())
				{
					maxposition = $(focus).height() - $(parentelement).height();
				}
				else
				{
					focus = $('body');
				}
			}
			else
			{
				focus = $('body');
			}
		 }

	 var rolled = 0;
	 if ('wheelDelta' in event) {
		 rolled = event.wheelDelta;
	 }
	 else {  // Firefox
		 // The measurement units of the detail and wheelDelta properties are different.
		 rolled = event.detail*(-120);
	 }
	 
	 //if ($(focus).data("positiondelta" )==undefined)
	 //$embellishment.data("embellishmentid",1)
	 if ($(focus)[0].getAttribute("positiondelta")==undefined)
		 
		 {
			 positiondelta = 0;
			 //console.log("positiondelta: undefined");
		 }
	 else
		 {
			 positiondelta = $(focus)[0].getAttribute("positiondelta");
			 //console.log("positiondelta: " + positiondelta);
		 }
	 positiondelta = positiondelta - rolled;
	 
	 
	 
	 //console.log("target:" + targetposition);
	//var targetposition = $(focus).scrollTop() + positiondelta;
	 /*
	 if (targetposition <= 0)
		 {
			 targetposition = -startposition;
			 //console.log("start")
		 }
	 
	 else if (targetposition+startposition >= maxposition)
		 {
			 targetposition = (maxposition-startposition);
			 //console.log("end")
		 }
	 else
		 {
			 
		 }
	 $(focus).data( "targetposition", targetposition );
	 */
	 
	 //console.log("document:" + $(document).height());
	 //console.log("window:" + $(window).height());

	 //position = startposition + targetposition;
	 //$(focus).data( "position", position );
	 //
	 //$(focus).data( "positiondelta", positiondelta );
	 $(focus)[0].setAttribute("positiondelta",positiondelta );
	 
	 UpdatePosition($(focus));
	 
	 //element.innerHTML = "";
	 //console.log("pos:" + position);
	 event.preventDefault();
	 return false;
 	}

	function Init (smoothscrollelem) {
		
		// for mouse scrolling in Firefox
		
		
		if (smoothscrollelem.addEventListener) {    // all browsers except IE before version 9
			// Internet Explorer, Opera, Google Chrome and Safari
			smoothscrollelem.addEventListener ("mousewheel", MouseScroll, false);
			// Firefox
			smoothscrollelem.addEventListener ("DOMMouseScroll", MouseScroll, false);
		}
		else {
			if (smoothscrollelem.attachEvent) { // IE before version 9
				smoothscrollelem.attachEvent ("onmousewheel", MouseScroll);
			}
		}
    }

	var elements = $('*');
	console.log("Loaded " + elements.length + " scrollable elements.");
	$(elements).each(function() {
		//if (this.scrollTop > this.height())
		//if ($(this).innerHeight()>$(this).outerHeight())
		//{
			//Init(window);
			//$(this).bind('mousewheel', function(e){
				//MouseScroll(e.originalEvent, this);
				//console.log("scrolling");
				//if(e.originalEvent.wheelDelta /120 > 0) {
				//$(this).text('scrolling up !');
				//}
				//else{
				//$(this).text('scrolling down !');
				//}
			//});
		//}
		$( this ).bind({
		  mousedown: function() {
			  focus = $(this);
		  },
		  mouseleave: function() {
			  //focus = $('body');
			  
		  }
		});
	});

$('body').bind('mousewheel', function(e){
	MouseScroll(e.originalEvent);
	//console.log("scrolling");
	//if(e.originalEvent.wheelDelta /120 > 0) {
	//$(this).text('scrolling up !');
	//}
	//else{
	//$(this).text('scrolling down !');
	//}
});


//Init(window);																																				 
console.log("Smoothscroll loaded!");