Add button for Smooth Scroll to the top / bottom

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

Ajankohdalta 11.6.2015. Katso uusin versio.

  1. // ==UserScript==
  2. // @name Add button for Smooth Scroll to the top / bottom
  3. // @author burningall
  4. // @description 为页面添加按钮,平滑的滚动到顶部/底部
  5. // @version 2015.6.11.1
  6. // @include *
  7. // @grant GM_addStyle
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @grant GM_listValues
  11. // @grant GM_deleteValue
  12. // @supportURL http://www.burningall.com
  13. // @contributionURL troy450409405@gmail.com|alipay.com
  14. // @namespace https://greatest.deepsurf.us/zh-CN/users/3400-axetroy
  15. // ==/UserScript==
  16.  
  17.  
  18. //========快捷键列表=======
  19. //【Ctrl+F2】>>>>>调出控制面板
  20. //【Ctrl+Alt】>>>>呼出按钮
  21. //【alt+1】>>>>>>>向上滚动
  22. //【alt+2】>>>>>>>向下滚动
  23. //【Esc】>>>>>>>>>退出控制面板
  24.  
  25. (function(){
  26. function checkList(){
  27. if( GM_getValue(window.top.location.host,'不在黑名单中')==window.top.location.host ){//如果该页面在黑名单中,则不执行
  28. return true;
  29. };
  30. };
  31. var d1=new Date().getTime()
  32. //================公共函数区============
  33. function addEvent(obj, event, fn) {return obj.addEventListener ? obj.addEventListener(event, fn, false) : obj.attachEventListener("on" + event, fn);};
  34. function getSize(obj) {return document.documentElement[obj]!=0 ? document.documentElement[obj]: document.body[obj];}
  35. function hasScroll() {return getSize('scrollHeight') > getSize('clientHeight') ? true : false;};
  36. function getStyle(obj, attr) {return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];}
  37. function $(id) {return document.getElementById(id);}
  38. function doMove(obj, attr, dir, target, endFn) {
  39. dir = parseInt(getStyle(obj, attr)) < target ? dir: -dir;
  40. clearInterval(obj.timer);
  41. obj.timer = setInterval(function() {
  42. var speed = parseInt(getStyle(obj, attr)) + dir;
  43. if (speed > target && dir > 0 || speed < target && dir < 0) {
  44. speed = target;
  45. };
  46. obj.style[attr] = speed + "px";
  47. if (speed == target) {
  48. clearInterval(obj.timer);
  49. endFn && endFn();
  50. };
  51. },
  52. 30);
  53. };
  54. //================样式区============
  55. var cssText='\
  56. #scrollMars-troy{\
  57. position:fixed !important;\
  58. right:30px;\
  59. z-index:9999999 !important;\
  60. }\
  61. \
  62. .sroll-btn-troy{\
  63. width:40px !important;\
  64. height:40px !important;\
  65. text-align:center !important;\
  66. padding:5px !important;\
  67. background:#303030 !important;\
  68. color:#fff !important;\
  69. display:block !important;\
  70. opacity:0.8 !important;\
  71. fitter:alpha(opacity:80) !important;\
  72. cursor:pointer !important;\
  73. border-radius:50% !important;\
  74. box-shadow:2px 2px 40px 2px #303030 !important;\
  75. line-height:40px !important;\
  76. font-size:35px !important;\
  77. font-style:inherit !important;\
  78. font-weight:bold !important;\
  79. font-family:"宋体" !important;\
  80. }\
  81. #scrollMars-troy>div>div:hover{\
  82. background:#FF0000 !important;\
  83. }\
  84. #mars-point{\
  85. width:100px !important;\
  86. height:100px !important;\
  87. position:absolute !important;\
  88. top:0 !important;\
  89. left:-40px !important;\
  90. }\
  91. #setting-troy{\
  92. width: 300px !important;\
  93. height: auto !important;\
  94. border: 2px solid #303030 !important;\
  95. position: fixed !important;\
  96. top: 200px !important;\
  97. left: 33% !important;\
  98. color: #fff !important;\
  99. background: #303030 !important;\
  100. z-index:9999999999 !important;\
  101. }\
  102. #setting-troy>div{\
  103. margin: 20px !important;\
  104. }\
  105. #setting-troy>div input{\
  106. color:#fff !important;\
  107. background:#303030 !important;\
  108. padding:5px !important;\
  109. margin:5px !important;\
  110. }\
  111. #percent{\
  112. position:absolute !important;\
  113. top:42px !important;\
  114. left:-20px;\
  115. color:#147474 !important;\
  116. font-family:"微软雅黑" !important;\
  117. font-size:16px !important;\
  118. line-height:16px !important;\
  119. }\
  120. '
  121. GM_addStyle(cssText);
  122. //================主要代码区============
  123. GM_getValue("turn") ? GM_setValue("turn",true) : GM_setValue("turn",GM_getValue("turn"));
  124. function readmode(speed,inteval,endFn){
  125. if( !$('percent') || GM_getValue("turn")==false || createBtn()==false ){
  126. return;
  127. }
  128. clearInterval(document.readMode);
  129. document.readMode=setInterval(function(){
  130. var position=getSize('scrollTop')+speed;
  131. document.body.scrollTop = document.documentElement.scrollTop = position;
  132. clearTimeout(document.showPercent);
  133. var precent=parseInt( getSize('scrollTop') / ( getSize('scrollHeight')-getSize('clientHeight') ) * 100);
  134. $('percent').style.display="block";
  135. $('percent').innerHTML=precent+'%';
  136. if (position + getSize('clientHeight') >= getSize('scrollHeight')) {//如果滚到底部
  137. clearInterval(document.readMode);
  138. $('percent').style.display="none";
  139. }
  140. },inteval)
  141. GM_setValue("turn",true);
  142. }
  143. function moveMars(obj,index){
  144. if(index=='mouseout'){
  145. clearTimeout(obj.timerHover);
  146. obj.timerHover = setTimeout(function() {
  147. doMove(obj, "right", 5, -30);
  148. },
  149. 3000);//鼠标离开后,3s隐藏到边栏
  150. }else if(index=='mouseover'){
  151. clearTimeout(obj.timerHover);
  152. doMove(obj, "right", 5, 30);
  153. }
  154. }
  155. function scroll(obj,dir){//obj随意,dir>0往上滚,dir<0往下滚
  156. clearInterval(obj.timerScroll);
  157. clearInterval(document.readMode);
  158. obj.timerScroll=setInterval(function(){
  159. var position;
  160. if(dir>0){//往上滚动
  161. var speed = (getSize('scrollTop') / 10) + 10;
  162. position = getSize('scrollTop') - speed;
  163. if (position <= 0) {//如果滚到顶部
  164. document.body.scrollTop = document.documentElement.scrollTop = 0;
  165. clearInterval(obj.timerScroll);
  166. }
  167. }else{//往下滚动
  168. var speed = ((getSize('scrollHeight')-getSize('scrollTop')) / 20) + 10;
  169. position = getSize('scrollTop') + speed;
  170. if (position + getSize('clientHeight') >= getSize('scrollHeight')) {//如果滚到底部
  171. document.body.scrollTop = document.documentElement.scrollTop = getSize('scrollHeight');
  172. clearInterval(obj.timerScroll);
  173. }
  174. }
  175. document.body.scrollTop = document.documentElement.scrollTop = position;
  176. },20)
  177. }
  178. function createBtn(){
  179. if(checkList()==true){
  180. return false;
  181. }
  182. var jugg=$("scrollMars-troy");
  183. if(jugg && hasScroll() == true){//如果有滚动条,并且存在滚动按钮
  184. $('scrollMars-troy').style.top=(getSize('clientHeight')/3)+'px';//调整按钮位置
  185. }else if(jugg && hasScroll() == false){//如果没有滚动条,但是有按钮
  186. jugg.remove(jugg);//删除按钮
  187. };
  188. if (hasScroll() == false && !jugg) {//如果没有滚动条,并且没有按钮
  189. return false;
  190. }else if(hasScroll() == true && !jugg){//如果有滚动条,并且没有按钮
  191. var mars=document.createElement('div');
  192. mars.id="scrollMars-troy";
  193. window.top.document.documentElement.appendChild(mars);
  194. mars.innerHTML = "\
  195. <div id='percent'></div>\
  196. <div id='mars-point'></div>\
  197. <div>\
  198. <div id='goTop-troy' title='返回顶部' class='sroll-btn-troy'></div>\
  199. <div id='goBtn-troy' title='去到底部' class='sroll-btn-troy'></div>\
  200. </div>\
  201. ";
  202. $('scrollMars-troy').style.top=(getSize('clientHeight')/3)+'px';
  203. $("goTop-troy").innerHTML = "↑";
  204. $("goBtn-troy").innerHTML = "↓";
  205. addEvent($("goTop-troy"), "click",function() {scroll(mars,1)});
  206. addEvent($("goBtn-troy"), "click",function() {scroll(mars,-1)});
  207. addEvent($("mars-point"), "mouseover",function(e) {moveMars(mars,"mouseover");});
  208. addEvent($("mars-point"), "mouseout",function(e) {moveMars(mars,"mouseout");});
  209. addEvent(mars, "mouseover",function() {moveMars(mars,"mouseover")});
  210. addEvent(window, "resize",function() {$('scrollMars-troy').style.top=(getSize('clientHeight')/3)+'px';});
  211. moveMars(mars,"mouseout");//页面加载完成,默认3s后隐藏到边栏
  212. return true;
  213. };
  214. };
  215. //================执行区============
  216. addEvent(window,'mousewheel',function(){//滚动则停止,兼容chrome/ie/opera
  217. createBtn() && clearInterval($('scrollMars-troy').timerScroll);
  218. })
  219.  
  220. addEvent(window,'DOMMouseScroll',function(){//滚动则停止,兼容firefox
  221. createBtn() && clearInterval($('scrollMars-troy').timerScroll);
  222. })
  223.  
  224. addEvent(document,'dblclick',function(event){//双击进入阅读模式
  225. var type=/input|form|textarea|img|a|li|object|video|audio/ig;
  226. event=event || window.event;
  227. var macType=type.test(event.target.nodeName);
  228. if(macType){
  229. return;
  230. };
  231. readmode(1,20);
  232. })
  233.  
  234. addEvent(document,'click',function(){//单击退出阅读模式
  235. if($('percent')){
  236. clearInterval(document.readMode);
  237. $('percent').style.display="none";
  238. }
  239. })
  240.  
  241. addEvent(window.top, "resize",function(){//页面大小改变,初始化按钮
  242. createBtn();
  243. });
  244.  
  245. addEvent(window.top,"load",function(){//页面加载,初始化按钮
  246. createBtn();
  247. var d2=new Date().getTime();
  248. console.log('GoTop-GoBtm脚本加载耗时:'+(d2-d1)+'ms');
  249. });
  250. //================快捷键区============
  251. addEvent(window,'keydown',function(event){
  252. event=event || window.event;
  253. if(event.altKey && event.keyCode==49){//alt+1,向上滚动
  254. scroll($('scrollMars-troy'),1)
  255. }else if(event.altKey && event.keyCode==50){//alt+2,向下滚动
  256. scroll($('scrollMars-troy'),-1)
  257. }else if(event.ctrlKey && event.altKey){//ctrl+alt,调出按钮
  258. moveMars($('scrollMars-troy'),"mouseover");
  259. setTimeout(function(){
  260. moveMars($('scrollMars-troy'),"mouseout");
  261. },3000);
  262. }else if(event.keyCode==27){//Esc退出控制面板
  263. var setting=$('setting-troy');
  264. setting && setting.remove(setting);
  265. }else if(event.ctrlKey && event.keyCode==113){//ctrl+F2,调处控制面板
  266. $('setting-troy') && setting.remove(setting);
  267. var setting=document.createElement('div');
  268. setting.id='setting-troy';
  269. var inner="\
  270. <div id='setting-pan-troy'>\
  271. <div>\
  272. 控制面板:Ctrl+F2<br />\
  273. 添加黑名单域名:<input type='text' id='blackList' placeholder='www.baidu.com' /><br />\
  274. <input type='button' value='添加黑名单' id='saveSetting' />\
  275. <input type='button' id='quiet' value='退出面板(Esc)' /><br/><hr />\
  276. <input type='button' id='clear' value='移除黑名单'>\
  277. <input type='button' id='showlist' value='显示黑名单'>\
  278. <input type='button' id='clearall' value='清空黑名单'>\
  279. <input type='button' id='readmodebtn' value='双击滚动开关'>\
  280. </div>\
  281. </div>\
  282. "
  283. window.top.document.documentElement.appendChild(setting);
  284. setting.innerHTML=inner;
  285. //var domian=/^[0-9-a-z]{0,}\.{0,1}[0-9-a-z]+\.{0,1}[a-z]{0,}\.{1}[a-z]+$/ig;//用于验证域名是否符合规范
  286. var domian=/^[0-9a-zA-Z]+[0-9a-zA-Z\.-]*\.[a-zA-Z]{2,4}$/;
  287. var host=window.top.location.host;
  288. $('blackList').value=host;
  289. //GM_setValue("turn",true);//第一次安装脚本,默认开启双击滚动
  290. addEvent($('quiet'),'click',function(){//退出
  291. setting.remove(setting);
  292. });
  293. addEvent($('clear'),'click',function(){//移出黑名单
  294. alert( GM_getValue($('blackList').value,'未获取')+":移除成功" );
  295. GM_deleteValue($('blackList').value);
  296. });
  297. addEvent($('clearall'),'click',function(){//清空黑名单
  298. for(var i=0;i<GM_listValues().length;i++){
  299. if(domian.test( GM_listValues()[i] )==true){
  300. console.log('黑名单:'+GM_listValues()[i]+'被删除');
  301. GM_deleteValue( GM_listValues()[i] );
  302. }
  303. };//for
  304. alert('清空完毕,\nBug:可能需要多点几次,才能清空');
  305. })
  306. addEvent($('showlist'),'click',function(){//显示黑名单
  307. if(GM_listValues().length<=1){
  308. alert('空的黑名单');
  309. return;
  310. }else{
  311. for(var i=0;i<GM_listValues().length;i++){
  312. if(domian.test( GM_listValues()[i] )==true){
  313. var list=document.createElement('li');
  314. list.innerHTML=GM_listValues()[i];
  315. document.querySelector('#setting-pan-troy>div').appendChild(list);
  316. }
  317. }//for
  318. }
  319. });
  320. addEvent($('readmodebtn'),'click',function(){//禁用双击滚动
  321. console.log("当前状态:"+GM_getValue("turn"),"空的变量");
  322. if( GM_getValue("turn")==true ){
  323. GM_setValue("turn",false);
  324. alert('开关状态:'+GM_getValue("turn")+',禁用成功');
  325. return;
  326. }else if(GM_getValue("turn")==false){
  327. GM_setValue("turn",true);
  328. alert('开关状态:'+GM_getValue("turn")+',开启成功');
  329. return;
  330. }
  331. })
  332. addEvent($('saveSetting'),'click',function(){//保存
  333. if(domian.test($('blackList').value)==false){//检查输入的域名是否符合规范
  334. alert($('blackList').value+'域名格式不正确'+'\n比如:tieba.baidu.com或www.baidu.com')
  335. return;
  336. }else if($('blackList').value!=''){//如果有填入黑名单列表
  337. if( GM_getValue($('blackList').value,'不存在这个黑名单')!=$('blackList').value ){//不在黑名单中
  338. GM_setValue($('blackList').value,$('blackList').value);
  339. alert('禁用:'+$('blackList').value+'成功');
  340. }else{
  341. alert('该域名已在黑名单中');
  342. }
  343. }else{//没有填入黑名单
  344. alert('请输入域名');
  345. return;
  346. }
  347. })
  348. }
  349. })//监听keydown,快捷键
  350. /*
  351. //清除GM脚本保存的所有变量;,调试时用,请不要开启
  352. function clearallGM_value(){
  353. for(var i=0;i<GM_listValues().length;i++){
  354. console.log('变量:'+GM_listValues()[i]+'被删除');
  355. GM_deleteValue( GM_listValues()[i] );
  356. };
  357. }
  358. clearallGM_value()
  359. */
  360. })()