Wait For Selector

Waits for selectors to match newly added nodes

当前为 2021-09-14 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/432418/970669/Wait%20For%20Selector.js

  1. // ==UserScript==
  2. // @name Wait For Selector
  3. // @version 0.1.0
  4. // @description Waits for selectors to match newly added nodes
  5. // @author Kumirei
  6. // @include *community.wanikani.com*
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. (function($) {
  11. // Create new observer on body to monitor all DOM changes
  12. let observer = new MutationObserver(mutationHandler)
  13. observer.observe(document.getElementsByTagName('body')[0], {childList: true, subtree: true})
  14.  
  15. // Interface for interacting with the library
  16. let interface = {
  17. version: GM_info.script.version,
  18. observer: observer,
  19. wait: waitForSelector,
  20. unwait: unwaitID,
  21. waits: {},
  22. waitsByID: {},
  23. nextID: 0
  24. }
  25.  
  26. // Start
  27. installInterface()
  28.  
  29. // Creates a new entry to search for whenever a new element is added to the DOM
  30. function waitForSelector(preSelector, selector, callback) {
  31. if (selector.match(`${preSelector}$`) === null) throw ('preSelector must match the end of the selector')
  32. if (!interface.waits[selector]) interface.waits[selector] = {}
  33. interface.waits[selector][interface.nextID] = callback
  34. interface.waits[selector].pre = preSelector
  35. interface.waitsByID[interface.nextID] = selector
  36. return interface.nextID++
  37. }
  38.  
  39. // Deletes a previously registered selector
  40. function unwaitID(ID) {
  41. delete interface.waits[interface.waitsByID[ID]][ID]
  42. }
  43.  
  44. // Makes sure that the public interface is the newest version and the same as the local one
  45. function installInterface() {
  46. let wfs = window.wkfe
  47. if (!wfs) window.wfs = interface
  48. else if (wfs.version < interface.version) {
  49. wfs.version = interface.version
  50. wfs.observer.disconnect()
  51. wfs.observer = interface.observer
  52. wfs.wait = interface.wait
  53. wfs.unwait = interface.unwait
  54. }
  55. interface = wfs || interface
  56. }
  57.  
  58. // Searches the added nodes and matches them with the provided selectors. Calls the callback for every match.
  59. function mutationHandler(mutations) {
  60. for (let mutation of mutations) {
  61. let added = mutation.addedNodes
  62. for (let node of added) {
  63. if (node.nodeType === 1) {
  64. let sibling = node.previousElementSibling
  65. let target = sibling ? sibling : node.parentElement
  66. for (let selector in interface.waits) {
  67. let query = (sibling?'+ ':'> ')+interface.waits[selector].pre
  68. $(target).find(query).each((i, e)=>{
  69. $(selector).each((I, E)=>{
  70. if (e.isSameNode(E)) {
  71. for (let callback of Object.values(interface.waits[selector])) {
  72. if (typeof callback === "function") callback(E)
  73. }
  74. }
  75. })
  76. })
  77. }
  78. }
  79. }
  80. }
  81. }
  82. })(window.jQuery);