Wait For Elements

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

当前为 2016-08-15 提交的版本,查看 最新版本

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

  1. /**
  2. * @param sel - the selector you want to wait for
  3. * @param action - the callback that will be executed when element/s matching the given selector are found, it is passed the array of found elements
  4. * @param stopLooking - if true the function will stop looking for more elements after the first match
  5. */
  6. function waitForElems(sel, action, stopLooking) {
  7. var tick;
  8. var id = 'fke' + Math.floor(Math.random() * 12345);
  9. var type = window.MutationObserver ? 'M' : 'S';
  10. var lastMutation = Date.now();
  11. var lastCall = Date.now();
  12. var queuedCall;
  13.  
  14. function throttle(func) {
  15. var now = Date.now();
  16. clearTimeout(queuedCall);
  17. // less than 100ms since last mutation
  18. if (now - lastMutation < 100) {
  19. // 500ms or more since last query
  20. if (now - lastCall >= 500) {
  21. func();
  22. }
  23. else {
  24. queuedCall = setTimeout(func, 100);
  25. }
  26. }
  27. else {
  28. func();
  29. }
  30. lastMutation = now;
  31. }
  32.  
  33. function findElem(sel) {
  34. lastCall = Date.now();
  35. var found = [].filter.call(document.querySelectorAll(sel), function(elem) {
  36. return elem.dataset[id] !== 'y';
  37. });
  38. if (found.length > 0) {
  39. if (stopLooking) {
  40. type === 'M' ? tick.disconnect() : clearInterval(tick);
  41. }
  42. found.forEach(function(elem) {
  43. elem.dataset[id] = 'y';
  44. action(elem);
  45. });
  46. }
  47. }
  48. if (type === 'M') {
  49. tick = new MutationObserver(throttle.bind(null, findElem.bind(null, sel)));
  50. tick.observe(document.body, {
  51. subtree: true,
  52. childList: true
  53. });
  54. }
  55. else {
  56. tick = setInterval(findElem.bind(null, sel), 300);
  57. }
  58. findElem(sel);
  59. return {
  60. type: type,
  61. stop: function() {
  62. if (type === 'M') {
  63. tick.disconnect();
  64. }
  65. else {
  66. clearInterval(tick);
  67. }
  68. }
  69. };
  70. }
  71. /**
  72. * @param regex - should match the site you're waiting for
  73. * @param action - the callback that will be executed when a matching url is visited
  74. * @param stopLooking - if true the function will stop waiting for another url match after the first match
  75. */
  76. function waitForUrl(regex, action, stopLooking) {
  77. function checkUrl(urlTest) {
  78. var url = window.location.href;
  79. if (url !== lastUrl && urlTest(url)) {
  80. if (stopLooking) {
  81. clearInterval(tick);
  82. }
  83. lastUrl = url;
  84. action();
  85. }
  86. lastUrl = url;
  87. }
  88. var urlTest = (typeof regex === 'function' ? regex : regex.test.bind(regex)),
  89. tick = setInterval(checkUrl.bind(null, urlTest), 300),
  90. lastUrl;
  91. checkUrl(urlTest);
  92. return tick;
  93. }