Don't fuck with my scroll!!!

Whenever the user scrolls using the mouse wheel it will disable all methods to programmatically scroll for 500 ms (0.5 seconds). Basically preventing websites to implement custom scrolling behaviors like smooth scrolling.

  1. // ==UserScript==
  2. // @name Don't fuck with my scroll!!!
  3. // @namespace http://github.com/YePpHa
  4. // @version 1.1
  5. // @description Whenever the user scrolls using the mouse wheel it will disable all methods to programmatically scroll for 500 ms (0.5 seconds). Basically preventing websites to implement custom scrolling behaviors like smooth scrolling.
  6. // @author Jeppe Rune Mortensen <jepperm@gmail.com>
  7. // @match http://*/*
  8. // @match https://*/*
  9. // @grant none
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. var inject = function() {
  17. // Change this value to decide how long it would take before restoring the
  18. // default scrolling methods.
  19. var timeout = 1000; // in milliseconds (there's 1000 ms in a second)
  20.  
  21. // Prevent websites from cancelling the default action of the scroll wheel.
  22. WheelEvent.prototype.preventDefault = function() {};
  23.  
  24. function init() {
  25. function enableScrolling() {
  26. window.scrollBy = _scrollBy;
  27. window.scrollTo = _scrollTo;
  28. Object.defineProperty(scrollingElement, "scrollTop", {
  29. configurable: true,
  30. enumerable: false,
  31. get: _scrollTopGetter,
  32. set: _scrollTopSetter
  33. });
  34. }
  35.  
  36. function disableScrolling() {
  37. window.scrollBy = _void;
  38. window.scrollTo = _void;
  39. Object.defineProperty(scrollingElement, "scrollTop", {
  40. configurable: true,
  41. enumerable: false,
  42. get: _scrollTopGetter,
  43. set: _void
  44. });
  45. }
  46.  
  47. function scrollHandler() {
  48. disableScrolling();
  49.  
  50. // Restore normal scrolling functionality after a certain delay. If the
  51. // user is still scrolling after we set the delay. Delete our delay and
  52. // start a new one instead. This is to only allow the scrolling to be
  53. // enabled after the user has stopped scrolling for x amount of time.
  54. clearTimeout(timer);
  55. timer = setTimeout(enableScrolling, timeout);
  56. }
  57.  
  58. // Keep a reference of the scrolling element as we will change the
  59. // `scrollTop` definition on it whenever the user scrolls.
  60. var scrollingElement = document.scrollingElement;
  61.  
  62. // Keep a list of all the original functions that we will replace
  63. // temporarily.
  64. var _scrollBy = window.scrollBy;
  65. var _scrollTo = window.scrollTo;
  66. var _scrollTopGetter = scrollingElement.__lookupGetter__("scrollTop");
  67. var _scrollTopSetter = scrollingElement.__lookupSetter__("scrollTop");
  68.  
  69. // Let's also define our void function as we really don't need to create a
  70. // new one every single time.
  71. var _void = function() {};
  72. var timer;
  73.  
  74. // Make sure that we're doing this synchronous (not passive) and as soon
  75. // as possible (in the capture phase) as we actually need to make sure
  76. // that we do our stuff first before websites can touch the scrolling.
  77. scrollingElement.addEventListener("wheel", scrollHandler, {
  78. passive: false,
  79. capture: true
  80. });
  81. window.addEventListener("wheel", scrollHandler, {
  82. passive: false,
  83. capture: true
  84. });
  85. scrollingElement.addEventListener("mousewheel", scrollHandler, {
  86. passive: false,
  87. capture: true
  88. });
  89. window.addEventListener("mousewheel", scrollHandler, {
  90. passive: false,
  91. capture: true
  92. });
  93. }
  94.  
  95. function isReady() {
  96. // We could probably do this a lot sooner, but for now let's try to do it
  97. // after the DOM has loaded and accessible.
  98. return document.readyState === "complete"
  99. || document.readyState === "interactive";
  100. }
  101.  
  102. function handleReadyStateChange() {
  103. if (isReady()) {
  104. document.removeEventListener("readystatechange", handleReadyStateChange, false);
  105. init();
  106. }
  107. }
  108. // Are we ready to actually add the scroll/wheel event listeners to the main
  109. // scrolling element? If not, wait for it to be ready by listening for the
  110. // `readystatechange` event.
  111. if (isReady()) {
  112. init();
  113. } else {
  114. document.addEventListener("readystatechange", handleReadyStateChange, false);
  115. }
  116. };
  117.  
  118. // We want to execute our code in the page context as we actually need to
  119. // modify properties that the website is accessing.
  120. var script = document.createElement("script");
  121. script.type = "text/javascript";
  122. script.appendChild(document.createTextNode('(' + inject.toString() + ')();'));
  123.  
  124. var scriptParent = document.body || document.head || document.documentElement;
  125. scriptParent.appendChild(script);
  126. })();