DONE - Visual Sign Of A Loaded Page

Shows a big DONE sign when the page is fully loaded

当前为 2014-08-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name DONE - Visual Sign Of A Loaded Page
  3. // @namespace http://userscripts.org/users/23652
  4. // @description Shows a big DONE sign when the page is fully loaded
  5. // @include http://*.*/*
  6. // @include https://*.*/*
  7. // @copyright JoeSimmons
  8. // @version 1.0.1
  9. // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
  10. // @grant GM_addStyle
  11. // ==/UserScript==
  12.  
  13. +function () {
  14. 'use strict';
  15.  
  16. // temporary fade function until I implement one in JSL
  17. function fade(dir, element) {
  18. var interval = 0.05,
  19. fps = Math.floor(1000 / 60),
  20. count, intv;
  21.  
  22. function anim() {
  23. var curOpacity = parseFloat(element.style.opacity);
  24.  
  25. if (dir === 'in') {
  26. if (curOpacity >= 1) {
  27. count = 1;
  28. element.style.opacity = '1';
  29. window.clearInterval(intv);
  30. } else {
  31. element.style.opacity = (count += interval);
  32. }
  33. } else if (dir === 'out') {
  34. if (curOpacity <= 0) {
  35. count = 0;
  36. element.style.opacity = '0';
  37. element.style.display = 'none';
  38. window.clearInterval(intv);
  39. } else {
  40. element.style.opacity = (count -= interval);
  41. }
  42. }
  43. }
  44.  
  45. if (typeof element === 'string') {
  46. element = document.getElementById(element);
  47. }
  48.  
  49. if (dir === 'in') {
  50. element.style.opacity = '0';
  51. count = 0;
  52.  
  53. if (element.style.display === 'none') {
  54. element.style.display = '';
  55. }
  56. } else if (dir === 'out') {
  57. element.style.opacity = '1';
  58. count = 1;
  59. } else {
  60. return;
  61. }
  62.  
  63. intv = window.setInterval(anim, fps);
  64. }
  65.  
  66. // runAfterPageIdle by JoeSimmons
  67. // supply it a function and it will run when the page stops mutating
  68. function runAfterPageIdle(fn) {
  69. 'use strict'; // can remove if parent is running in strict already; would save some bytes
  70.  
  71. var time = Date.now(),
  72. set = window.setInterval.bind(window),
  73. clear = window.clearInterval.bind(window),
  74. idleTime = 500, // adjustable -- the time after which the page has been idle, the user's function will run
  75. intv;
  76.  
  77. function listen(a) {
  78. var now = Date.now(); // why call Date.now() twice? :)
  79.  
  80. if (typeof a === 'undefined' && (now - time) >= idleTime) {
  81. // clear if it's been idle for the set length of time
  82. done();
  83. } else if (typeof a === 'object') {
  84. // reset if it hasn't been idle for the set length of time
  85. time = now;
  86. }
  87. }
  88.  
  89. function done() {
  90. // clear the interval
  91. clear(intv);
  92.  
  93. // remove listeners
  94. document.removeEventListener('DOMSubtreeModified', listen, false);
  95. document.removeEventListener('DOMNodeInserted', listen, false);
  96. document.removeEventListener('DOMNodeRemoved', listen, false);
  97.  
  98. // run user at next event loop slot
  99. window.setTimeout(fn, 0);
  100. }
  101.  
  102. if (typeof JSL !== 'undefined' && typeof JSL.setInterval === 'function' && typeof JSL.clearInterval === 'function') {
  103. set = JSL.setInterval.bind(JSL);
  104. clear = JSL.clearInterval.bind(JSL);
  105. }
  106.  
  107. if (typeof fn === 'function') {
  108. intv = set(listen, 125); // check 8 times per second
  109.  
  110. // set listeners
  111. document.addEventListener('DOMSubtreeModified', listen, false);
  112. document.addEventListener('DOMNodeInserted', listen, false);
  113. document.addEventListener('DOMNodeRemoved', listen, false);
  114. }
  115. }
  116.  
  117. function main() {
  118. var box = document.createElement('div'),
  119. boxWidth = Math.floor(window.innerWidth * 0.95);
  120.  
  121. GM_addStyle('' +
  122. '#load_sign { ' +
  123. 'background: #D7FFD7; ' +
  124. 'border: 3px ridge #008000; ' +
  125. 'color: #00C400; ' +
  126. 'display: block; ' +
  127. 'font-style: Arial; ' +
  128. 'font-size: 24pt; ' +
  129. 'height: 42px; ' +
  130. 'left: ' + (window.innerWidth / 2 - boxWidth / 2) + 'px; ' + // division comes first here so it works
  131. 'margin: 0 auto; ' +
  132. 'min-height: 42px; ' +
  133. 'padding: 4px 0; ' +
  134. 'position: fixed; ' +
  135. 'text-align: center; ' +
  136. 'text-shadow: 2px 2px 4px #C7C7C7; ' +
  137. 'top: 0; ' +
  138. 'width: ' + boxWidth + 'px; ' +
  139. 'z-index: 2100100100; ' +
  140. '}' +
  141. '');
  142.  
  143. box.id = 'load_sign';
  144. box.appendChild( document.createTextNode('LOADED') );
  145. document.body.appendChild(box);
  146.  
  147. window.setTimeout(function () {
  148. fade('out', 'load_sign');
  149. }, 750);
  150. }
  151.  
  152. // make sure the page is not in a frame
  153. if (window.frameElement || window !== window.top) { return; }
  154.  
  155. runAfterPageIdle(main);
  156. }();