Lite Add button for Smooth Scroll to the top / bottom

为页面添加按钮,平滑的滚动到顶部/底部

  1. // ==UserScript==
  2. // @name Lite Add button for Smooth Scroll to the top / bottom
  3. // @author burningall
  4. // @description 为页面添加按钮,平滑的滚动到顶部/底部
  5. // @version 2015.8.17
  6. // @include *
  7. // @grant GM_addStyle
  8. // @run-at document-start
  9. // @compatible chrome 完美支持
  10. // @compatible firefox 完美支持
  11. // @license The MIT License (MIT); http://opensource.org/licenses/MIT
  12. // @supportURL http://www.burningall.com
  13. // @contributionURL troy450409405@gmail.com|alipay.com
  14. // @namespace https://greasyfork.org/zh-CN/users/3400-axetroy
  15. // ==/UserScript==
  16. //
  17. //
  18. //
  19. //=======快捷键======
  20. //alt+1>>>>>>回到顶部
  21. //alt+2>>>>>>去到底部
  22. //================公共函数区============
  23. (function(window,document){
  24.  
  25. function addEvent(obj, type, fn){
  26. return obj.addEventListener ?
  27. obj.addEventListener(type, function(e){
  28. var ev = window.event ? window.event : (e ? e : null);
  29. ev.target = ev.target || ev.srcElement;
  30. if( fn.call(obj,ev)===false ){//回掉函数为false,则阻止默认时间
  31. e.cancelBubble = true;//阻止冒泡
  32. e.preventDefault();//chrome,firefox下阻止默认事件
  33. }
  34. }, false)
  35. :
  36. obj.attachEvent('on' + type, function(e){
  37. //fn.call(obj,e);//解决IE8下,this是window的问题
  38. var ev = window.event ? window.event : (e ? e : null);
  39. ev.target = ev.target || ev.srcElement;
  40. if(fn.call(obj,ev)===false ){
  41. e.cancelBubble = true;//阻止冒泡
  42. return false;//阻止默认事件,针对IE8
  43. }
  44. });
  45. }
  46.  
  47. function getSize(obj) {
  48. return document.documentElement[obj] !== 0 ? document.documentElement[obj] : document.body[obj];
  49. }
  50.  
  51. function hasScroll() {
  52. return getSize('scrollHeight') > getSize('clientHeight') ? true : false;
  53. }
  54.  
  55. function getStyle(obj, attr) {
  56. return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
  57. }
  58.  
  59. function $(id) {
  60. return document.getElementById(id);
  61. }
  62. function animate(obj,json,cfgjson){
  63. clearInterval(obj.animate);
  64. obj.animate = setInterval(function() {
  65. var bStop = true;//判断运动是否停止
  66. for(var attr in json){//attr代表属性,'width','height'.而json[attr]代表数值
  67. // 1. 取得当前的值(可以是width,height,opacity等的值)
  68. var objAttr = 0 ;
  69. if(attr == 'opacity'){ //当前值
  70. objAttr = Math.round(parseFloat( getStyle(obj,attr) ) * 100);
  71. }else if( attr=="scrollTop" ){
  72. objAttr = parseInt( getSize("scrollTop") );
  73. }
  74. else{
  75. objAttr = parseInt( getStyle(obj,attr) );
  76. }
  77. // 2.计算运动速度
  78. var jsonattr = parseFloat( json[attr] );//目标值
  79. var speedConfig = (cfgjson && typeof ( cfgjson.speed ) != 'undefined') ? cfgjson.speed : 10;
  80. var iSpeed = (jsonattr - objAttr) / speedConfig; //(目标数值-当前数值)/10
  81. iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //如果速度>0,则速度向上取整,如果小于0,则保留小数
  82. // 3. 检测所有运动是否到达目标
  83. //objAttr,当前点,json[attr]为目标点
  84. if ( (iSpeed>0 && objAttr <= jsonattr) || (iSpeed<0 && objAttr >= jsonattr) ) {//如果有其中一项没有达到目标
  85. bStop = false;
  86. }
  87. if (attr == "opacity") {
  88. obj.style.filter = 'alpha(opacity:' + (objAttr + iSpeed) + ')';
  89. obj.style.opacity = (objAttr + iSpeed) / 100;
  90. }else if(attr == "scrollTop"){
  91. document.documentElement.scrollTop=document.body.scrollTop = objAttr+iSpeed;
  92. }
  93. else {
  94. obj.style[attr] = objAttr + iSpeed + 'px'; //赋值开始运动
  95. }
  96. if (bStop) { // 表示所有运动都到达目标值
  97. clearInterval(obj.animate);
  98. if( cfgjson && typeof cfgjson.endFn != 'undefined' ){
  99. cfgjson.endFn.call(obj);
  100. }
  101. }
  102. }//for
  103. },20);
  104. }
  105. //================样式区============
  106. var cssText = '#scrollMars-troy{position:fixed;right:30px;z-index:9999999}#scrollMars-troy #mars-point{width:100px;height:100px;position:absolute;top:0;left:-40px}#scrollMars-troy div div.sroll-btn-troy{width:50px;height:50px;text-align:center;background:#303030;color:#fff;display:block;opacity:0.8;filter:alpha(opacity=80);cursor:pointer;border-radius:50%;box-shadow:2px 2px 40px 2px #303030;line-height:50px;font-size:35px;font-style:inherit;font-weight:bold;font-family:"宋体"}#scrollMars-troy div div.sroll-btn-troy:hover{background:#FF0000}';
  107. GM_addStyle(cssText);
  108. //================主要代码区============
  109. function scroll(dir) { //obj随意,dir>0往上滚,dir<0往下滚
  110. var position,speed,scrollTop,scrollHeight,clientHeight;
  111. clearInterval(document.timerScroll);
  112. scrollHeight = getSize('scrollHeight');
  113. clientHeight = getSize('clientHeight');
  114. document.timerScroll = setInterval(function() {
  115. scrollTop = getSize('scrollTop');
  116. if (dir > 0) { //往上滚动
  117. speed = ( scrollTop/10 ) + 1;
  118. position = scrollTop - speed;
  119. if (position <= 0) { //如果滚到顶部
  120. document.body.scrollTop = document.documentElement.scrollTop = 0;
  121. clearInterval(document.timerScroll);
  122. }
  123. } else { //往下滚动
  124. speed = ( (scrollHeight-scrollTop-clientHeight) / 10 ) + 1;
  125. position = scrollTop + speed;
  126. if (position + clientHeight >= scrollHeight) { //如果滚到底部
  127. document.body.scrollTop = document.documentElement.scrollTop = scrollHeight;
  128. clearInterval(document.timerScroll);
  129. }
  130. }
  131. document.body.scrollTop = document.documentElement.scrollTop = position;
  132. }, 20);
  133. }
  134.  
  135. function marsMove(dir){
  136. var mars = $('scrollMars-troy');
  137. var point = $('mars-point');
  138. if(dir=="moveIn"){//移入
  139. clearTimeout(mars.timerHover);
  140. animate(mars,{"right":"30","opacity":"100"});
  141. animate(point,{"left":"0"});
  142. }else if(dir=="moveOut"){//移出
  143. clearTimeout(mars.timerHover);
  144. mars.timerHover = setTimeout(function(){
  145. animate(mars,{"right":"-30","opacity":"30"});
  146. animate(point,{"left":"-40"});
  147. },3000);
  148. }
  149. }
  150.  
  151. function init() {
  152. var scrollBtn = $("scrollMars-troy");
  153. if( scrollBtn ){
  154. scrollBtn.style.top = (getSize('clientHeight') / 3) + 'px';
  155. }
  156. if (hasScroll() === true && !scrollBtn) { //如果有滚动条,并且没有按钮
  157. var mars = document.createElement('div'),goTop,goBtm,point;
  158. mars.id = "scrollMars-troy";
  159. window.top.document.documentElement.appendChild(mars);
  160. mars.innerHTML =
  161. '<div id=\'mars-point\'></div>'+
  162. '<div>'+
  163. ' <div id=\'goTop-troy\' title=\'返回顶部\' class=\'sroll-btn-troy\'></div>'+
  164. ' <div id=\'goBtm-troy\' title=\'去到底部\' class=\'sroll-btn-troy\'></div>'+
  165. '</div>';
  166. goTop = $("goTop-troy");
  167. goBtm = $("goBtm-troy");
  168. goTop.innerHTML = "↑";
  169. goBtm.innerHTML = "↓";
  170. $('scrollMars-troy').style.top = (getSize('clientHeight') / 3) + 'px';
  171. addEvent(goTop, "click", function() {
  172. scroll(1);
  173. return false;
  174. });
  175. addEvent(goBtm, "click", function() {
  176. scroll(-1);
  177. return false;
  178. });
  179. addEvent(mars,'mouseover',function(){
  180. marsMove("moveIn");
  181. return false;
  182. });
  183. addEvent(mars,'mouseout',function(){
  184. marsMove("moveOut");
  185. return false;
  186. });
  187. addEvent(mars,'mousedown',function(){
  188. return false;
  189. });
  190. marsMove("moveOut");
  191. }
  192. }
  193. //================执行区============
  194. addEvent(window,"mousewheel",function(){
  195. clearInterval(document.timerScroll);
  196. });
  197. addEvent(window,"DOMMouseScroll",function(){
  198. clearInterval(document.timerScroll);
  199. });
  200. addEvent(window.top, "resize", function() { //页面大小改变,初始化按钮
  201. init();
  202. });
  203.  
  204. addEvent(document, 'DOMContentLoaded', function() {
  205. init();
  206. });
  207. //================快捷键区============
  208. addEvent(window, 'keydown', function(e) {
  209. if (e.altKey && e.keyCode == 49) { //alt+1,向上滚动
  210. scroll(1);
  211. } else if (e.altKey && e.keyCode == 50) { //alt+2,向下滚动
  212. scroll(-1);
  213. } else if (e.ctrlKey && e.altKey) { //ctrl+alt,调出按钮
  214. marsMove("moveIn");
  215. }
  216. });//监听keydown,快捷键
  217.  
  218. })(window,document);