点击复制

对所有网站生效,支持SPA(比如vue)动态插入的input和select。比如可以自动填写用户名和密码,自动点击同意协议。浏览器需要安装Tampermonkey或者Greasemonkey扩展,安卓手机浏览器推荐Yandex或者Kiwi浏览器。

  1. // ==UserScript==
  2. // @name fill the input and select of form as last time inputed automatically
  3. // @name:zh-CN 点击复制
  4. // @namespace http://tampermonkey.net/
  5. // @description This script supports SPA like vue。
  6. // @description:zh-CN 对所有网站生效,支持SPA(比如vue)动态插入的input和select。比如可以自动填写用户名和密码,自动点击同意协议。浏览器需要安装Tampermonkey或者Greasemonkey扩展,安卓手机浏览器推荐Yandex或者Kiwi浏览器。
  7. // @require https://gf.qytechs.cn/scripts/440334-jquery-like-spa-operation-library/code/jQuery-like%20SPA%20operation%20library.js?version= 1020513
  8. // @include https://*axshare.com/*
  9. // @include http://showdoc.*
  10. // @include http://10.216.115.73*
  11. // @include https://js.design/*
  12. // @include https://lanhuapp.com/web/*
  13. // @include https://www.uviewui.com/*
  14. // @include C:/*
  15. // @include */tool/swagger
  16. // @include */api/swagger-ui/*
  17. // @include https://www.apifox.cn/*
  18. // @include https://echarts.apache.org/zh/option.html*
  19. // @exclude https://www.apifox.cn/apidoc/auth*
  20. // @grant GM_setClipboard
  21. // @grant GM_setValue
  22. // @grant GM_getValue
  23. // @author yechenyin
  24. // @license MIT
  25. // @version 1.0.4
  26. // ==/UserScript==
  27.  
  28. //console.debug = ()=>{}
  29. console.info('点击复制');
  30.  
  31. (function () {
  32. var jQuery = function (selector) {
  33. return new jQuery.fn.init(selector)
  34. }
  35. jQuery.fn = jQuery.prototype = {
  36. length: 0,
  37. selector: '',
  38. init: function (elementOrSelector) {
  39. var nodes = []
  40. if (typeof elementOrSelector == 'string') {
  41. this.selector = elementOrSelector
  42. nodes = document.querySelectorAll(this.selector)
  43. } else if (elementOrSelector instanceof NodeList) {
  44. nodes = elementOrSelector
  45. } else if (elementOrSelector instanceof Element) {
  46. nodes = [elementOrSelector]
  47. }
  48. this.length = nodes.length
  49. for (var i = 0; i < nodes.length; i++) {
  50. this[i] = nodes[i]
  51. }
  52. },
  53. each: function (callback) {
  54. for (var i = 0; i < this.length; i++) {
  55. callback.call(this[i])
  56. }
  57. },
  58. on: function (event, callback) {
  59. this.each(function () {
  60. this.addEventListener(event, callback)
  61. })
  62. },
  63. text: function (string) {
  64. var i = 0
  65. if (string !== undefined) {
  66. for (i = 0; i < this.length; i++) {
  67. this[i].innerText = string
  68. }
  69. } else {
  70. return this[0].innerText
  71. }
  72. },
  73. val: function (value) {
  74. if (value === undefined) {
  75. var ret
  76. if (this[0].type == 'checkbox') ret = this[0].checked
  77. else if (
  78. this[0].type == 'radio' ||
  79. this[0].type == 'text' ||
  80. this[0].type == 'password' ||
  81. this[0].tagName == 'select'
  82. )
  83. ret = this[0].value
  84. return ret
  85. } else {
  86. for (var i = 0; i < this.length; i++) {
  87. if (this[i].type == 'checkbox' && Boolean(value)) this[i].click()
  88. else if (this[i].type == 'radio')
  89. this[i].checked = this[i].value == value
  90. else if (this[i].type == 'text') this[i].value = value
  91. else if (this[i].type == 'password') this[i].value = value
  92. else if (this[i].tagName == 'select') this[i].value = value
  93. this[i].dispatchEvent(new Event('input', { bubbles: true }))
  94. }
  95. }
  96. },
  97. attr: function (attribute, value) {
  98. if (value === undefined) {
  99. return this[0].getAttribute(attribute)
  100. } else {
  101. this.each(function () {
  102. this.setAttribute(attribute, value)
  103. })
  104. }
  105. },
  106. click: function () {
  107. this[0].click()
  108. },
  109. find: function (selector) {
  110. var j = 0
  111. var result = []
  112. for (var i = 0; i < this.length; i++) {
  113. if (this[i].querySelectorAll(selector).length) {
  114. }
  115. }
  116. },
  117. append: function (html) {
  118. for (var i = 0; i < this.length; i++) {
  119. this[i].innerHTML += html
  120. }
  121. },
  122. }
  123.  
  124. jQuery.fn.init.prototype = jQuery.fn
  125. if (!window.jQuery) window.jQuery = window.$ = jQuery
  126. })()
  127.  
  128. //每当符合选择器规则的元素插入到页面中时,唤起callback方法。如果trigger_once为true,只唤起一次
  129. jQuery.fn.inserted = function (callback, trigger_once = false) {
  130. var selector = this.selector
  131. if ($(selector).length > 0) {
  132. //console.debug($(selector).length + ' ' + selector + " is loaded at begin");
  133. callback.call($(selector))
  134. }
  135. var finished = false
  136. var recall = function (mutationsList, observer) {
  137. for (var i = 0; i < mutationsList.length; i++) {
  138. //console.debug(mutationsList[i].target)
  139. if (mutationsList[i].addedNodes) {
  140. for (var j = 0; j < mutationsList[i].addedNodes.length; j++) {
  141. var element = mutationsList[i].addedNodes[j]
  142. if (
  143. !(trigger_once && finished) &&
  144. element instanceof Element &&
  145. element.querySelectorAll(selector).length
  146. ) {
  147. var container = ''
  148. if (element.id) container = '#' + element.id
  149. else if (element.className) container = '.' + element.className
  150. else container = element.outerHtml
  151. //console.debug(container + ' which contains ' + selector + ' is loaded')
  152. if (trigger_once) {
  153. observer.disconnect()
  154. finished = true
  155. }
  156. callback.call($(element.querySelectorAll(selector)))
  157. }
  158. }
  159. }
  160. }
  161. }
  162. var MutationObserver =
  163. window.MutationObserver ||
  164. window.WebKitMutationObserver ||
  165. window.MozMutationObserver
  166. if (MutationObserver) {
  167. var observer = new MutationObserver(recall)
  168. observer.observe(document.body, {
  169. childList: true,
  170. subtree: true,
  171. })
  172. }
  173. }
  174.  
  175. if (location.href.indexOf('https://lanhuapp.com/web/#/item/project/') == 0) {
  176. $('.item_content').inserted(function () {
  177. var text = this[0].innerText
  178. console.debug('item_content ' + text)
  179. copyTextToClipboard(text)
  180. this[0].addEventListener(
  181. 'DOMCharacterDataModified',
  182. function (event) {
  183. var text = event.newValue
  184. console.debug('DOMCharacterDataModified ' + text)
  185. copyTextToClipboard(text)
  186. },
  187. false
  188. )
  189. })
  190. } else {
  191. $('.opblock').inserted(function () {
  192. this[0].addEventListener(
  193. 'click',
  194. (event) => {
  195. console.debug('mouseup')
  196. var text = ''
  197. if (window.getSelection().toString()) {
  198. text = window.getSelection().toString()
  199. console.debug('window selection ' + text)
  200. } else if (document.selection) {
  201. text = document.selection.createRange().text
  202. console.debug('document selection ' + text)
  203. } else {
  204. text = event.target.innerText
  205. console.debug('click ' + text)
  206. }
  207. copyTextToClipboard(text)
  208. },
  209. true
  210. )
  211. })
  212.  
  213. window.addEventListener(
  214. 'mouseup',
  215. (event) => {
  216. console.debug('mouseup')
  217. var text = ''
  218. if (window.getSelection().toString()) {
  219. text = window.getSelection().toString()
  220. console.debug('window selection ' + text)
  221. } else if (document.selection) {
  222. text = document.selection.createRange().text
  223. console.debug('document selection ' + text)
  224. } else {
  225. text = event.target.innerText
  226. console.debug('click ' + text)
  227. }
  228. copyTextToClipboard(text)
  229. },
  230. true
  231. )
  232. }
  233.  
  234. function copyTextToClipboard(text) {
  235. if (!text) return
  236. text = text.trim().replaceAll('"', '')
  237. text = text.replaceAll('​', '')
  238. text = text.replaceAll('/dev-api/api', '')
  239. text = text.replaceAll('/dev-api/api', '')
  240. if (GM_setClipboard) {
  241. GM_setClipboard(text)
  242. return
  243. }
  244. if (navigator.clipboard) {
  245. navigator.clipboard.writeText(text).then(
  246. function () {
  247. console.debug('Copy was successful!', text)
  248. },
  249. function (err) {
  250. console.error('Async: Could not copy text: ', err)
  251. }
  252. )
  253. } else {
  254. if (window.clipboardData && window.clipboardData.setData) {
  255. // Internet Explorer-specific code path to prevent textarea being shown while diaconsole.debug is visible.
  256. return window.clipboardData.setData('Text', text)
  257. } else {
  258. var textArea = document.createElement('textarea')
  259. textArea.value = text
  260.  
  261. // Avoid scrolling to bottom
  262. textArea.style.top = '0'
  263. textArea.style.left = '0'
  264. textArea.style.position = 'fixed'
  265.  
  266. document.body.appendChild(textArea)
  267. textArea.focus()
  268. textArea.select()
  269.  
  270. try {
  271. var successful = document.execCommand('copy')
  272. var msg = successful ? 'successful' : 'unsuccessful'
  273. console.debug('Fallback: Copying text command was ' + msg)
  274. } catch (err) {
  275. console.error('Fallback: Oops, unable to copy', err)
  276. } finally {
  277. document.body.removeChild(textArea)
  278. }
  279. return
  280. }
  281. }
  282. }
  283.  
  284. function copyToClipboard(text) {
  285. if (window.clipboardData && window.clipboardData.setData) {
  286. // Internet Explorer-specific code path to prevent textarea being shown while diaconsole.debug is visible.
  287. return window.clipboardData.setData('Text', text)
  288. } else if (
  289. document.queryCommandSupported &&
  290. document.queryCommandSupported('copy')
  291. ) {
  292. var textarea = document.createElement('textarea')
  293. textarea.textContent = text
  294. textarea.style.position = 'fixed' // Prevent scrolling to bottom of page in Microsoft Edge.
  295. document.body.appendChild(textarea)
  296. textarea.select()
  297. try {
  298. return document.execCommand('copy') // Security exception may be thrown by some browsers.
  299. } catch (ex) {
  300. console.warn('Copy to clipboard failed.', ex)
  301. return prompt('Copy to clipboard: Ctrl+C, Enter', text)
  302. } finally {
  303. document.body.removeChild(textarea)
  304. }
  305. }
  306. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址