DisableScrollScript

禁止滚动

  1. // ==UserScript==
  2. // @name DisableScrollScript
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024.11.18.4
  5. // @description 禁止滚动
  6. // @author 荷塘月色
  7. // @include *://*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. const wrapper = document.createElement('div')
  14. document.body.appendChild(wrapper)
  15. wrapper.classList.add('custom-wrapper')
  16. const dragEl = document.createElement('div')
  17. dragEl.classList.add('custom-drag-element')
  18. const defaultStyleClass = document.createElement('style')
  19. const hiddenStyleClass = document.createElement('style')
  20. const button = document.createElement('button')
  21. wrapper.appendChild(button)
  22. wrapper.appendChild(dragEl)
  23. document.head.appendChild(defaultStyleClass)
  24. button.innerText = '锁定'
  25. button.classList.add('custom-button')
  26.  
  27. const offset = { x: 0, y: 0 }
  28. let isDragging = false
  29.  
  30. dragEl.addEventListener('touchstart', e => {
  31. isDragging = true
  32. const touch = e.touches[0] // 获取第一个触摸点
  33. offset.x = touch.clientX - wrapper.getBoundingClientRect().left
  34. offset.y = touch.clientY - wrapper.getBoundingClientRect().top
  35. e.preventDefault()
  36. })
  37.  
  38. dragEl.addEventListener('mousedown', (ev) => {
  39. isDragging = true
  40. offset.x = ev.clientX - wrapper.getBoundingClientRect().left
  41. offset.y = ev.clientY - wrapper.getBoundingClientRect().top
  42. })
  43.  
  44. document.addEventListener('mousemove', function(e) {
  45. if (isDragging) {
  46. wrapper.style.left = (e.clientX - offset.x) + 'px'
  47. wrapper.style.top = (e.clientY - offset.y) + 'px'
  48. }
  49. })
  50.  
  51. document.addEventListener('mouseup', function() {
  52. isDragging = false
  53. })
  54.  
  55. document.addEventListener('touchmove', function(e) {
  56. if (isDragging) {
  57. const touch = e.touches[0] // 获取第一个触摸点
  58. wrapper.style.left = (touch.clientX - offset.x) + 'px'
  59. wrapper.style.top = (touch.clientY - offset.y) + 'px'
  60. }
  61. })
  62.  
  63. document.addEventListener('touchend', function() {
  64. isDragging = false
  65. })
  66.  
  67. button.addEventListener('click', () => {
  68. if (document.head.contains(hiddenStyleClass)) {
  69. document.head.removeChild(hiddenStyleClass)
  70. button.innerText = '锁定'
  71. } else {
  72. document.head.appendChild(hiddenStyleClass)
  73. button.innerText = '解锁'
  74. }
  75. })
  76.  
  77. function Camel2Kebab(string) {
  78. return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
  79. }
  80.  
  81. /* 通用 JSON 转 CSS 方法 */
  82. function Json2Css(complexStyleObject) {
  83. let cssString = ''
  84.  
  85. for (const selector in complexStyleObject) {
  86. if (selector.startsWith('@')) { /* 处理媒体查询和其他@规则 */
  87. cssString += `${selector} { `
  88. for (const innerSelector in complexStyleObject[selector]) {
  89. cssString += `${innerSelector} { `
  90. const styles = complexStyleObject[selector][innerSelector]
  91. for (const prop in styles) {
  92. cssString += `${Camel2Kebab(prop)}: ${styles[prop]}; `
  93. }
  94. cssString += '} '
  95. }
  96. cssString += '} '
  97. } else {
  98. cssString += `${selector} { `
  99. const styles = complexStyleObject[selector]
  100. for (const prop in styles) {
  101. cssString += `${Camel2Kebab(prop)}: ${styles[prop]}; `
  102. }
  103. cssString += '} '
  104. }
  105. }
  106.  
  107. return cssString
  108. }
  109.  
  110. const hiddenStylesJSON = {
  111. '*': {
  112. // 'overflow': 'hidden !important',
  113. // 'touch-action': 'none'
  114. }
  115. }
  116. hiddenStyleClass.innerHTML = `${Json2Css(hiddenStylesJSON)}`
  117.  
  118. const defaultStylesJSON = {
  119. '.custom-wrapper': {
  120. 'zIndex': '10000',
  121. 'position': 'fixed',
  122. 'top': '10px',
  123. 'left': '10px',
  124. 'padding': '4px',
  125. 'display': 'flex',
  126. 'flexDirection': 'column',
  127. 'gap': '4px',
  128. 'background': 'rgb(255,255,255)',
  129. 'border-radius': '2px',
  130. 'border': '1px solid #666',
  131. 'box-sizing': 'border-box',
  132. },
  133. '.custom-button': {
  134. 'padding': '0.25em 1em',
  135. // 'border-radius': '4px 4px 0 0',
  136. 'border-radius': '2px',
  137. 'border': '1px solid #666',
  138. 'cursor': 'pointer',
  139. 'color': '#333',
  140. 'font-size': '0.875em',
  141. 'box-sizing': 'border-box',
  142. },
  143. '.custom-drag-element': {
  144. 'width': '100%',
  145. 'height': '6px',
  146. 'background': 'rgba(0,0,0,0.25)',
  147. 'border': '1px solid #666',
  148. // 'border-radius': '0 0 4px 4px',
  149. 'border-radius': '2px',
  150. 'cursor': 'pointer',
  151. 'box-sizing': 'border-box',
  152. }
  153. }
  154. defaultStyleClass.innerHTML = `${Json2Css(defaultStylesJSON)}`
  155.  
  156. function preventScroll(e) {
  157. if (document.head.contains(hiddenStyleClass))
  158. e.preventDefault()
  159. }
  160.  
  161. window.addEventListener('wheel', preventScroll, { passive: false }) // 鼠标滚轮
  162. window.addEventListener('touchmove', preventScroll, { passive: false }) // 移动设备触摸滑动
  163.  
  164. // 确保按钮能在页面里
  165. setInterval(() => {
  166. if (!document.body.contains(wrapper)) {
  167. document.body.appendChild(wrapper)
  168. }
  169. }, 100)
  170. })()