Wait For Elements

given a selector waits for elements to be inserted into the DOM and executes a callback for each match

Questo script non dovrebbe essere installato direttamente. È una libreria per altri script da includere con la chiave // @require https://update.greatest.deepsurf.us/scripts/5679/250853/Wait%20For%20Elements.js

  1. /**
  2. * @param obj - {
  3. * sel: 'a', // the selector you want to wait for (optional)
  4. * context: document.body, // scope of search for selector or mutations (optional, default document.body)
  5. * stop: true, // stop waiting after first result (optional, default false)
  6. * mode: 'M', // M to use mutation observer, S to use setInterval (optional, default M)
  7. * onchange: func, // if using mode 'M' this function will be called whenever mutation handler triggers
  8. * onmatch: func, // if selector is specified function will be called for each match with element as parameter
  9. * config: { attributes: true } // if using mode 'M' this object will override settings passed to mutation observer
  10. * }
  11. */
  12. function waitForElems(obj) {
  13. var tick;
  14. var id = 'fke' + Math.floor(Math.random() * 12345);
  15. var type = window.MutationObserver ? (obj.mode || 'M') : 'S';
  16. var lastMutation = Date.now();
  17. var lastCall = Date.now();
  18. var context = obj.context || document.body;
  19. var sel = obj.sel;
  20. var config = obj.config || {
  21. subtree: true,
  22. childList: true
  23. };
  24. var onChange = obj.onchange;
  25. var queuedCall;
  26.  
  27. function throttle(func) {
  28. var now = Date.now();
  29. clearTimeout(queuedCall);
  30. // less than 100ms since last mutation
  31. if (now - lastMutation < 100) {
  32. // 500ms or more since last query
  33. if (now - lastCall >= 500) {
  34. func();
  35. } else {
  36. queuedCall = setTimeout(func, 100);
  37. }
  38. } else {
  39. func();
  40. }
  41. lastMutation = now;
  42. }
  43.  
  44. function findElem(sel) {
  45. lastCall = Date.now();
  46. var found = [].filter.call(context.querySelectorAll(sel), function(elem) {
  47. return elem.dataset[id] !== 'y';
  48. });
  49. if (found.length > 0) {
  50. if (obj.stop) {
  51. type === 'M' ? tick.disconnect() : clearInterval(tick);
  52. }
  53. found.forEach(function(elem) {
  54. elem.dataset[id] = 'y';
  55. obj.onmatch(elem);
  56. });
  57. }
  58. }
  59. if (type === 'M') {
  60. tick = new MutationObserver(function() {
  61. if (sel) throttle.call(null, findElem.bind(null, sel));
  62. if (onChange) onChange.apply(this, arguments);
  63. });
  64. tick.observe(context, config);
  65. } else {
  66. tick = setInterval(findElem.bind(null, sel), 300);
  67. }
  68. if (sel) findElem(sel);
  69. return {
  70. type: type,
  71. stop: function() {
  72. if (type === 'M') {
  73. tick.disconnect();
  74. } else {
  75. clearInterval(tick);
  76. }
  77. },
  78. resume: function() {
  79. if (type === 'M') {
  80. tick.observe(context, config);
  81. } else {
  82. tick = setInterval(findElem.bind(null, sel), 300);
  83. }
  84. }
  85. };
  86. }
  87. /**
  88. * @param regex - should match the site you're waiting for
  89. * @param action - the callback that will be executed when a matching url is visited
  90. * @param stopLooking - if true the function will stop waiting for another url match after the first match
  91. */
  92. function waitForUrl(regex, action, stopLooking) {
  93. function checkUrl(urlTest) {
  94. var url = window.location.href;
  95. if (url !== lastUrl && urlTest(url)) {
  96. if (stopLooking) {
  97. clearInterval(tick);
  98. }
  99. lastUrl = url;
  100. action();
  101. }
  102. lastUrl = url;
  103. }
  104. var urlTest = (typeof regex === 'function' ? regex : regex.test.bind(regex)),
  105. tick = setInterval(checkUrl.bind(null, urlTest), 300),
  106. lastUrl;
  107. checkUrl(urlTest);
  108. return tick;
  109. }