observer.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { getWindow } from 'ssr-window';
  2. import { elementParents } from '../../../shared/utils.js';
  3. export default function Observer({
  4. swiper,
  5. extendParams,
  6. on,
  7. emit
  8. }) {
  9. const observers = [];
  10. const window = getWindow();
  11. const attach = (target, options = {}) => {
  12. const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
  13. const observer = new ObserverFunc(mutations => {
  14. // The observerUpdate event should only be triggered
  15. // once despite the number of mutations. Additional
  16. // triggers are redundant and are very costly
  17. if (swiper.__preventObserver__) return;
  18. if (mutations.length === 1) {
  19. emit('observerUpdate', mutations[0]);
  20. return;
  21. }
  22. const observerUpdate = function observerUpdate() {
  23. emit('observerUpdate', mutations[0]);
  24. };
  25. if (window.requestAnimationFrame) {
  26. window.requestAnimationFrame(observerUpdate);
  27. } else {
  28. window.setTimeout(observerUpdate, 0);
  29. }
  30. });
  31. observer.observe(target, {
  32. attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
  33. childList: typeof options.childList === 'undefined' ? true : options.childList,
  34. characterData: typeof options.characterData === 'undefined' ? true : options.characterData
  35. });
  36. observers.push(observer);
  37. };
  38. const init = () => {
  39. if (!swiper.params.observer) return;
  40. if (swiper.params.observeParents) {
  41. const containerParents = elementParents(swiper.el);
  42. for (let i = 0; i < containerParents.length; i += 1) {
  43. attach(containerParents[i]);
  44. }
  45. }
  46. // Observe container
  47. attach(swiper.el, {
  48. childList: swiper.params.observeSlideChildren
  49. });
  50. // Observe wrapper
  51. attach(swiper.wrapperEl, {
  52. attributes: false
  53. });
  54. };
  55. const destroy = () => {
  56. observers.forEach(observer => {
  57. observer.disconnect();
  58. });
  59. observers.splice(0, observers.length);
  60. };
  61. extendParams({
  62. observer: false,
  63. observeParents: false,
  64. observeSlideChildren: false
  65. });
  66. on('init', init);
  67. on('destroy', destroy);
  68. }