PageSourceSearch

https://www.visionsource-esplineyes.com/scripts/js-swiper-component.js

js visionsource-esplineyes.com collected 2026-10-08 09:40:01 UTC 9,756 bytes, 284 lines download raw bytes

1import Swiper from "https://cdn.jsdelivr.net/npm/[email protected]/swiper-bundle.min.mjs";
2export default function swiperComponent(options = {}) {
3  return {
4    swiper: null,
5    initialized: false,
6    $options: options,
7    swiperInstanceId: options.id || `swiper-${Date.now()}-${Math.floor(Math.random() * 1e3)}`,
8    swiperContainerSelector: null,
9    paginationSelector: null,
10    nextButtonSelector: null,
11    prevButtonSelector: null,
12    defaultOptions: {
13      slidesPerView: 1,
14      spaceBetween: 20,
15      autoplay: { delay: 3e3, disableOnInteraction: false },
16      loop: false,
17      effect: void 0,
18      displayMode: "mobile-only",
19
20      breakpoint: 740,
21      breakpointCustom: 980,
22      waitForLoad: false
23    },
24    init() {
25      this.prepareDOM();
26      this.$el.addEventListener("click", (e) => this.arrowClickFallback(e));
27      let resizeTimeout;
28      const debouncedResize = () => {
29        clearTimeout(resizeTimeout);
30        resizeTimeout = setTimeout(() => {
31          this.checkBreakpoint();
32        }, 150);
33      };
34      const onReady = () => {
35        setTimeout(() => {
36          this.checkBreakpoint();
37        }, 200);
38      };
39      if (document.readyState === "complete") {
40        onReady();
41      } else {
42        document.addEventListener("DOMContentLoaded", onReady);
43        window.addEventListener("load", () => {
44          setTimeout(() => {
45            this.checkBreakpoint();
46          }, 100);
47        });
48      }
49      window.addEventListener("resize", debouncedResize);
50    },
51
52    arrowClickFallback(e) {
53      const nav = this.$options.navigation;
54      if (!nav || !this.swiper) return;
55      const prevHit = nav.prevEl && e.target.closest(nav.prevEl);
56      const nextHit = nav.nextEl && e.target.closest(nav.nextEl);
57      if (!prevHit && !nextHit) return;
58      const hit = prevHit || nextHit;
59      const bound = prevHit ? this.prevButtonSelector : this.nextButtonSelector;
60      if (bound && hit.matches(bound)) return;
61      if (prevHit) this.swiper.slidePrev();
62      else this.swiper.slideNext();
63    },
64    prepareDOM() {
65      const swiperEl = this.$el.querySelector(".swiper");
66      if (!swiperEl) {
67        console.warn("Swiper container element not found");
68        return;
69      }
70      if (!swiperEl.id) swiperEl.id = this.swiperInstanceId;
71      this.swiperContainerSelector = `#${swiperEl.id}`;
72      if (this.$options.pagination !== false) {
73        let pag = null;
74        if (this.$options.pagination?.el) {
75          pag = this.$el.querySelector(this.$options.pagination.el);
76        }
77        if (!pag) {
78          pag = this.$el.querySelector(".swiper-pagination");
79        }
80        if (pag) {
81          const pid = `pagination-${this.swiperInstanceId}`;
82          pag.id = pid;
83          this.paginationSelector = `#${pid}`;
84        }
85      }
86      if (this.$options.navigation !== false) {
87        let prev = null;
88        let next = null;
89        if (this.$options.navigation?.prevEl) {
90          prev = this.$el.querySelector(this.$options.navigation.prevEl);
91        }
92        if (this.$options.navigation?.nextEl) {
93          next = this.$el.querySelector(this.$options.navigation.nextEl);
94        }
95        if (!prev) {
96          prev = this.$el.querySelector(".swiper-button-prev");
97        }
98        if (!next) {
99          next = this.$el.querySelector(".swiper-button-next");
100        }
101        if (prev) {
102          const prid = `prev-${this.swiperInstanceId}`;
103          prev.id = prid;
104          this.prevButtonSelector = `#${prid}`;
105        }
106        if (next) {
107          const nid = `next-${this.swiperInstanceId}`;
108          next.id = nid;
109          this.nextButtonSelector = `#${nid}`;
110        }
111      }
112    },
113    checkBreakpoint() {
114      const width = window.innerWidth;
115      const isMobile = width < this.defaultOptions.breakpoint;
116      const isCustom = width < this.defaultOptions.breakpointCustom;
117      let active = true;
118      switch (this.$options.displayMode || this.defaultOptions.displayMode) {
119        case "mobile-only":
120          active = isMobile;
121          break;
122        case "desktop-only":
123          active = !isMobile;
124          break;
125        case "custom":
126          active = isCustom;
127          break;
128        case "always":
129        default:
130          active = true;
131          break;
132      }
133      if (this.$el.offsetParent === null) active = false;
134      if (active && !this.initialized) {
135        setTimeout(() => this.initSwiper(), 100);
136      } else if (!active && this.initialized) {
137        this.destroySwiper();
138      } else if (active && this.initialized && this.swiper) {
139        setTimeout(() => {
140          if (this.swiper && this.swiper.update) {
141            this.swiper.update();
142            if (this.swiper.updateSlidesClasses) {
143              this.swiper.updateSlidesClasses();
144            }
145            if (this.swiper.updateSlides) {
146              this.swiper.updateSlides();
147            }
148            if (this.swiper.updateProgress) {
149              this.swiper.updateProgress();
150            }
151            if (this.swiper.pagination && this.swiper.pagination.update) {
152              this.swiper.pagination.update();
153            }
154          }
155        }, 50);
156      }
157    },
158    initSwiper() {
159      this.prepareDOM();
160      const minSlidesToInit = this.$options.minSlidesToInit || 1;
161      if (this.$el.querySelectorAll(".swiper-slide").length < minSlidesToInit) return;
162      const base = JSON.parse(JSON.stringify(this.defaultOptions));
163      const opts = Object.assign(base, this.$options);
164      if (opts.loop) {
165        const spvValues = [
166          opts.slidesPerView,
167          ...Object.values(opts.breakpoints || {}).map((b) => b.slidesPerView)
168        ].filter((v) => typeof v === "number");
169        const needed = Math.max(...spvValues, 1) + (opts.slidesPerGroup || 1);
170        if (this.$el.querySelectorAll(".swiper-slide").length < needed) {
171          opts.loop = false;
172          opts.rewind = true;
173        }
174      }
175      if (opts.pagination !== false && this.paginationSelector) {
176        opts.pagination = {
177          el: this.paginationSelector,
178          clickable: true,
179          type: "bullets",
180          dynamicBullets: false,
181          renderBullet: function(index, className) {
182            return '<span class="' + className + ' swiper-pagination-bullet-custom"></span>';
183          },
184          ...this.$options.paginationOptions || {}
185        };
186      } else {
187        opts.pagination = false;
188      }
189      if (opts.navigation !== false && this.prevButtonSelector && this.nextButtonSelector) {
190        opts.navigation = {
191          prevEl: this.prevButtonSelector,
192          nextEl: this.nextButtonSelector
193        };
194      } else {
195        opts.navigation = false;
196      }
197      if (["flip", "cube", "cards"].includes(opts.effect)) {
198        opts.slidesPerView = 1;
199        opts.slidesPerGroup = 1;
200      }
201      const originalOn = opts.on || {};
202      opts.on = {
203        ...originalOn,
204        init: function() {
205          if (originalOn.init) originalOn.init.call(this);
206          if (this.pagination && this.pagination.update) {
207            setTimeout(() => {
208              if (!this.pagination) return;
209              this.pagination.render();
210              this.pagination.update();
211            }, 10);
212          }
213        },
214        slideChange: function() {
215          if (originalOn.slideChange) originalOn.slideChange.call(this);
216          if (this.pagination) {
217            requestAnimationFrame(() => {
218              if (!this.pagination) return;
219              if (this.pagination.render) this.pagination.render();
220              if (this.pagination.update) this.pagination.update();
221            });
222          }
223        },
224        transitionStart: function() {
225          if (originalOn.transitionStart) originalOn.transitionStart.call(this);
226          if (this.pagination && this.pagination.update) {
227            this.pagination.update();
228          }
229        },
230        transitionEnd: function() {
231          if (originalOn.transitionEnd) originalOn.transitionEnd.call(this);
232          if (this.pagination) {
233            requestAnimationFrame(() => {
234              if (this.pagination && this.pagination.update) this.pagination.update();
235            });
236          }
237        },
238        touchMove: function() {
239          if (originalOn.touchMove) originalOn.touchMove.call(this);
240          if (this.pagination && this.pagination.update) {
241            this.pagination.update();
242          }
243        },
244        setTranslate: function() {
245          if (originalOn.setTranslate) originalOn.setTranslate.call(this);
246          if (this.pagination && this.pagination.update) {
247            this.pagination.update();
248          }
249        }
250      };
251      try {
252        this.swiper = new Swiper(this.swiperContainerSelector, opts);
253        if (this.swiper.pagination) {
254          setTimeout(() => {
255            if (!this.swiper || !this.swiper.pagination) return;
256            this.swiper.pagination.render();
257            this.swiper.pagination.update();
258          }, 100);
259        }
260        if (opts.autoplay && this.swiper.autoplay) {
261          setTimeout(() => {
262            if (this.swiper && this.swiper.autoplay) this.swiper.autoplay.start();
263          }, 100);
264        }
265        this.initialized = true;
266        if (typeof window !== "undefined") {
267          window.swiperInstance = this.swiper;
268        }
269      } catch (e) {
270        console.error("Swiper init error:", e);
271      }
272    },
273    destroySwiper() {
274      if (this.swiper) {
275        this.swiper.destroy(true, true);
276        this.swiper = null;
277      }
278      this.initialized = false;
279      if (typeof window !== "undefined" && window.swiperInstance === this.swiper) {
280        delete window.swiperInstance;
281      }
282    }
283  };
284}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.