node-creation-observer

Callback binding for HTML Node creation events

目前為 2017-02-11 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/19857/174436/node-creation-observer.js

  1. /**
  2. * https://github.com/soufianesakhi/node-creation-observer-js
  3. * MIT licensed
  4. * Copyright (c) 2016 Soufiane Sakhi
  5. */
  6. var NodeCreationObserver = function () {
  7. var mutationObserver = null;
  8. var observedNodeAttribute = "observed";
  9. var listeners = {};
  10. var options = {
  11. childList: true,
  12. subtree: true
  13. };
  14. var ListenerContext = (function () {
  15. function ListenerContext(removeOnFirstMatch) {
  16. this.callbacks = [];
  17. this.removeOnFirstMatch = removeOnFirstMatch == undefined ? false : removeOnFirstMatch;
  18. }
  19. return ListenerContext;
  20. }());
  21. function onMutationCallback() {
  22. Object.keys(listeners).forEach(function (selector) {
  23. invokeCallbacks(selector);
  24. });
  25. }
  26. function invokeCallbacks(selector) {
  27. var callbacks = listeners[selector].callbacks;
  28. var elements = document.querySelectorAll(selector);
  29. var newElements = filterNewElements(elements);
  30. if (newElements.length > 0) {
  31. if (listeners[selector].removeOnFirstMatch) {
  32. removeListener(selector);
  33. }
  34. newElements.forEach(function (element) {
  35. callbacks.forEach(function (callback) {
  36. callback.call(element, element);
  37. });
  38. });
  39. }
  40. }
  41. function filterNewElements(elements) {
  42. var newElements = [];
  43. for (var i = 0; i < elements.length; i++) {
  44. var element = elements[i];
  45. var attr = element.getAttribute(observedNodeAttribute);
  46. if (attr == null) {
  47. element.setAttribute(observedNodeAttribute, "1");
  48. newElements.push(element);
  49. }
  50. }
  51. ;
  52. return newElements;
  53. }
  54. function observe() {
  55. if (mutationObserver == null) {
  56. mutationObserver = new MutationObserver(onMutationCallback);
  57. mutationObserver.observe(document.documentElement, options);
  58. }
  59. }
  60. function removeListener(selector) {
  61. delete listeners[selector];
  62. if (Object.keys(listeners).length == 0) {
  63. stopObserving();
  64. }
  65. }
  66. function stopObserving() {
  67. if (mutationObserver != null) {
  68. mutationObserver.disconnect();
  69. mutationObserver = null;
  70. }
  71. }
  72. return {
  73. init: function (customObservedNodeAttribute) {
  74. observedNodeAttribute = customObservedNodeAttribute;
  75. },
  76. onCreation: function (selector, callback, removeOnFirstMatch) {
  77. if (!listeners[selector]) {
  78. listeners[selector] = new ListenerContext(removeOnFirstMatch);
  79. }
  80. listeners[selector].callbacks.push(callback);
  81. observe();
  82. if (document.querySelector(selector) != null) {
  83. invokeCallbacks(selector);
  84. }
  85. },
  86. remove: removeListener,
  87. stop: function () {
  88. listeners = {};
  89. stopObserving();
  90. }
  91. };
  92. }();