You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
1.5 KiB

  1. // Wrapper for IntersectionObserver in order to make working with it
  2. // a bit easier. We also follow this performance advice:
  3. // "If you need to observe multiple elements, it is both possible and
  4. // advised to observe multiple elements using the same IntersectionObserver
  5. // instance by calling observe() multiple times."
  6. // https://developers.google.com/web/updates/2016/04/intersectionobserver
  7. class IntersectionObserverWrapper {
  8. callbacks = {};
  9. observerBacklog = [];
  10. observer = null;
  11. connect (options) {
  12. const onIntersection = (entries) => {
  13. entries.forEach(entry => {
  14. const id = entry.target.getAttribute('data-id');
  15. if (this.callbacks[id]) {
  16. this.callbacks[id](entry);
  17. }
  18. });
  19. };
  20. this.observer = new IntersectionObserver(onIntersection, options);
  21. this.observerBacklog.forEach(([ id, node, callback ]) => {
  22. this.observe(id, node, callback);
  23. });
  24. this.observerBacklog = null;
  25. }
  26. observe (id, node, callback) {
  27. if (!this.observer) {
  28. this.observerBacklog.push([ id, node, callback ]);
  29. } else {
  30. this.callbacks[id] = callback;
  31. this.observer.observe(node);
  32. }
  33. }
  34. unobserve (id, node) {
  35. if (this.observer) {
  36. delete this.callbacks[id];
  37. this.observer.unobserve(node);
  38. }
  39. }
  40. disconnect () {
  41. if (this.observer) {
  42. this.callbacks = {};
  43. this.observer.disconnect();
  44. this.observer = null;
  45. }
  46. }
  47. }
  48. export default IntersectionObserverWrapper;