UNPKG

@tarojs/components

Version:
700 lines (699 loc) 23.1 kB
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _Swiper_id, _Swiper_source; import { h, Host } from '@stencil/core'; import classNames from 'classnames'; import SwiperJS from 'swiper/swiper-bundle.esm.js'; import { debounce } from '../../utils'; let INSTANCE_ID = 0; export class Swiper { constructor() { _Swiper_id.set(this, INSTANCE_ID++); _Swiper_source.set(this, ''); this.handleSwiperLoopListen = () => { var _a, _b, _c; ((_a = this.observerFirst) === null || _a === void 0 ? void 0 : _a.disconnect) && this.observerFirst.disconnect(); ((_b = this.observerLast) === null || _b === void 0 ? void 0 : _b.disconnect) && this.observerLast.disconnect(); this.observerFirst = new MutationObserver(this.handleSwiperLoopDebounce); this.observerLast = new MutationObserver(this.handleSwiperLoopDebounce); const wrapper = (_c = this.swiper.$wrapperEl) === null || _c === void 0 ? void 0 : _c[0]; const list = wrapper.querySelectorAll('taro-swiper-item-core:not(.swiper-slide-duplicate)'); if (list.length >= 1) { this.observerFirst.observe(list[0], { characterData: true }); } else if (list.length >= 2) { this.observerLast.observe(list[list.length - 1], { characterData: true }); } }; this.handleSwiperLoop = () => { var _a, _b, _c, _d; if (!this.swiper || !this.circular) return; const swiper = this.swiper; // Note: loop 相关的方法 swiper 未声明 const duplicates = ((_a = this.swiperWrapper) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.swiper-slide-duplicate')) || []; if (duplicates.length < 2) { // Note: 循环模式下,但是前后垫片未注入 (_b = swiper.loopDestroy) === null || _b === void 0 ? void 0 : _b.call(swiper); (_c = swiper.loopCreate) === null || _c === void 0 ? void 0 : _c.call(swiper); } else { (_d = swiper.loopFix) === null || _d === void 0 ? void 0 : _d.call(swiper); } }; this.handleSwiperLoopDebounce = debounce(this.handleSwiperLoop, 50); this.handleSwiperSizeDebounce = debounce(() => { if (this.swiper && this.swiper.$wrapperEl && !this.circular) { this.swiper.updateSlides(); } }, 50); this.swiperWrapper = undefined; this.swiper = undefined; this.isWillLoadCalled = false; this.indicatorDots = false; this.indicatorColor = 'rgba(0, 0, 0, .3)'; this.indicatorActiveColor = '#000000'; this.autoplay = false; this.current = 0; this.currentItemId = ''; this.interval = 5000; this.duration = 500; this.circular = false; this.vertical = false; this.previousMargin = '0px'; this.nextMargin = '0px'; this.displayMultipleItems = 1; this.full = false; this.zoom = false; this.observer = undefined; this.observerFirst = undefined; this.observerLast = undefined; } watchCurrent(newVal) { if (this.currentItemId || !this.isWillLoadCalled) return; const n = parseInt(newVal, 10); if (isNaN(n)) return; if (this.circular) { if (!this.swiper.isBeginning && !this.swiper.isEnd) { this.swiper.slideToLoop(n); // 更新下标 } } else { this.swiper.slideTo(n); // 更新下标 } } watchCurrentItemId(newVal) { var _a; const wrapper = (_a = this.swiper.$wrapperEl) === null || _a === void 0 ? void 0 : _a[0]; let itemIdIndex = 0; wrapper.querySelectorAll('taro-swiper-item-core:not(.swiper-slide-duplicate)').forEach((swiperItem, index) => { // @ts-ignore if (swiperItem.itemId && swiperItem.itemId === newVal) { itemIdIndex = index; } }); if (this.circular) { if (!this.swiper.isBeginning && !this.swiper.isEnd) { this.swiper.slideToLoop(itemIdIndex); // 更新下标 } } else { this.swiper.slideTo(itemIdIndex); // 更新下标 } } watchAutoplay(newVal) { if (!this.isWillLoadCalled || !this.swiper) return; const swiperAutoplay = this.swiper.autoplay; if (swiperAutoplay) { if (swiperAutoplay.running === newVal) return; if (newVal) { if (this.swiper.params && typeof this.swiper.params.autoplay === 'object') { if (this.swiper.params.autoplay.disableOnInteraction === true) { this.swiper.params.autoplay.disableOnInteraction = false; } this.swiper.params.autoplay.delay = this.interval; } swiperAutoplay.start(); } else { swiperAutoplay.stop(); } } } watchDuration(newVal) { if (!this.isWillLoadCalled) return; this.swiper.params.speed = newVal; } watchInterval(newVal) { if (!this.isWillLoadCalled) return; if (typeof this.swiper.params.autoplay === 'object') { this.swiper.params.autoplay.delay = newVal; } } watchSwiperWrapper(newVal) { if (!this.isWillLoadCalled) return; if (!newVal) return; this.el.appendChild = (newChild) => { return newVal.appendChild(newChild); }; this.el.insertBefore = (newChild, refChild) => { return newVal.insertBefore(newChild, refChild); }; this.el.replaceChild = (newChild, oldChild) => { return newVal.replaceChild(newChild, oldChild); }; this.el.removeChild = (oldChild) => { return newVal.removeChild(oldChild); }; this.el.addEventListener('DOMNodeInserted', this.handleSwiperSizeDebounce); this.el.addEventListener('DOMNodeRemoved', this.handleSwiperSizeDebounce); this.el.addEventListener('MutationObserver', this.handleSwiperSizeDebounce); } watchCircular() { if (this.swiper) { this.swiper.destroy(); this.handleInit(); } } watchDisplayMultipleItems() { if (this.swiper) { this.swiper.destroy(); this.handleInit(); } } componentWillLoad() { this.isWillLoadCalled = true; } componentDidLoad() { var _a; this.handleInit(); if (!this.swiper || !this.circular) return; const wrapper = (_a = this.swiper.$wrapperEl) === null || _a === void 0 ? void 0 : _a[0]; this.observer = new MutationObserver(this.handleSwiperLoopListen); this.observer.observe(wrapper, { childList: true }); } componentWillUpdate() { var _a, _b; if (!this.swiper) return; if (this.autoplay && !((_a = this.swiper.autoplay) === null || _a === void 0 ? void 0 : _a.running)) { (_b = this.swiper.autoplay) === null || _b === void 0 ? void 0 : _b.start(); } if (this.swiper.$el) { this.swiper.update(); // 更新子元素 } } componentDidRender() { this.handleSwiperLoop(); } disconnectedCallback() { var _a, _b, _c, _d, _e, _f; this.el.removeEventListener('DOMNodeInserted', this.handleSwiperSizeDebounce); this.el.removeEventListener('DOMNodeRemoved', this.handleSwiperSizeDebounce); this.el.removeEventListener('MutationObserver', this.handleSwiperSizeDebounce); (_b = (_a = this.observer) === null || _a === void 0 ? void 0 : _a.disconnect) === null || _b === void 0 ? void 0 : _b.call(_a); (_d = (_c = this.observerFirst) === null || _c === void 0 ? void 0 : _c.disconnect) === null || _d === void 0 ? void 0 : _d.call(_c); (_f = (_e = this.observerLast) === null || _e === void 0 ? void 0 : _e.disconnect) === null || _f === void 0 ? void 0 : _f.call(_e); } handleInit() { const { autoplay, circular, current, currentItemId, displayMultipleItems, duration, interval, vertical } = this; let initialSlide = circular ? current + 1 : current; if (currentItemId) { let itemIdIndex = 0; this.el.querySelectorAll('taro-swiper-item-core:not(.swiper-slide-duplicate)').forEach((swiperItem, index) => { // @ts-ignore if (swiperItem.itemId && swiperItem.itemId === currentItemId) { itemIdIndex = index; } }); initialSlide = circular ? itemIdIndex + 1 : itemIdIndex; } // eslint-disable-next-line @typescript-eslint/no-this-alias const that = this; const options = { pagination: { el: `.taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container > .swiper-pagination` }, direction: vertical ? 'vertical' : 'horizontal', loop: circular, slidesPerView: displayMultipleItems, initialSlide: initialSlide, speed: duration, observer: true, observeParents: true, zoom: this.zoom, on: { slideTo() { that.current = this.realIndex; }, // Note: slideChange 事件在 swiper.slideTo 改写 current 时不触发,因此用 slideChangeTransitionEnd 事件代替 slideChangeTransitionEnd() { /** Note: 此处不能使用 slideChangeTransitionStart 事件 * - 因为在它触发时 swiper 各个参数并未准备好,将会导致错误的事件抛出; * - 同时抛出 change 事件会导致 current 监听被打乱 swiper 的生命周期; * - 模式与 slideTo 结合时,会导致动画会被中断、slider 展示不完整或衔接模式错误等问题。 */ if (circular) { if (this.isBeginning || this.isEnd) { this.slideToLoop(this.realIndex, 0); // 更新下标 return; } } that.onChange.emit({ current: this.realIndex, source: __classPrivateFieldGet(that, _Swiper_source, "f"), }); }, touchEnd: () => { __classPrivateFieldSet(that, _Swiper_source, 'touch', "f"); }, autoplay() { __classPrivateFieldSet(that, _Swiper_source, 'autoplay', "f"); }, transitionEnd() { setTimeout(() => { __classPrivateFieldSet(that, _Swiper_source, '', "f"); }); that.onAnimationFinish.emit({ current: this.realIndex, source: __classPrivateFieldGet(that, _Swiper_source, "f"), }); }, observerUpdate(_swiper, e) { const target = e.target; const className = target && typeof target.className === 'string' ? target.className : ''; if (className.includes('taro_page') && target.style.display !== 'none') { if (that.autoplay && target.contains(_swiper.$el[0])) { if (that.circular) { _swiper.slideToLoop(this.realIndex, 0); // 更新下标 } else { _swiper.slideTo(this.realIndex); } } } } } }; // 自动播放 if (autoplay) { options.autoplay = { delay: interval, disableOnInteraction: false }; } this.swiper = new SwiperJS(`.taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container`, options); this.swiperWrapper = this.el.querySelector(`.taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container > .swiper-wrapper`); } render() { const { vertical, indicatorDots, indicatorColor, indicatorActiveColor } = this; const hostStyle = { overflow: 'hidden' }; const style = { overflow: 'visible' }; if (this.full) { hostStyle.height = '100%'; style.height = '100%'; } const [, previousMargin] = /^(\d+)px/.exec(this.previousMargin) || []; const [, nextMargin] = /^(\d+)px/.exec(this.nextMargin) || []; const pM = parseInt(previousMargin) || 0; const nM = parseInt(nextMargin) || 0; if (vertical) { style.marginTop = `${pM}px`; style.marginBottom = `${nM}px`; } else { style.marginRight = `${nM}px`; style.marginLeft = `${pM}px`; } return (h(Host, { class: `taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")}`, style: hostStyle }, h("div", { class: 'swiper-container', style: style }, h("style", { type: 'text/css' }, ` .taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container > .swiper-pagination > .swiper-pagination-bullet { background: ${indicatorColor} } .taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container > .swiper-pagination > .swiper-pagination-bullet-active { background: ${indicatorActiveColor} } `), h("div", { class: 'swiper-wrapper' }, h("slot", null)), h("div", { class: classNames('swiper-pagination', { 'swiper-pagination-hidden': !indicatorDots, 'swiper-pagination-bullets': indicatorDots }) })))); } static get is() { return "taro-swiper-core"; } static get originalStyleUrls() { return { "$": ["./style/index.scss"] }; } static get styleUrls() { return { "$": ["./style/index.css"] }; } static get properties() { return { "indicatorDots": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u662F\u5426\u663E\u793A\u9762\u677F\u6307\u793A\u70B9" }, "attribute": "indicator-dots", "reflect": false, "defaultValue": "false" }, "indicatorColor": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u6307\u793A\u70B9\u989C\u8272" }, "attribute": "indicator-color", "reflect": false, "defaultValue": "'rgba(0, 0, 0, .3)'" }, "indicatorActiveColor": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u5F53\u524D\u9009\u4E2D\u7684\u6307\u793A\u70B9\u989C\u8272" }, "attribute": "indicator-active-color", "reflect": false, "defaultValue": "'#000000'" }, "autoplay": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u662F\u5426\u81EA\u52A8\u5207\u6362" }, "attribute": "autoplay", "reflect": false, "defaultValue": "false" }, "current": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u5F53\u524D\u6240\u5728\u6ED1\u5757\u7684 index" }, "attribute": "current", "reflect": false, "defaultValue": "0" }, "currentItemId": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u5F53\u524D\u6240\u5728\u6ED1\u5757\u7684 item-id" }, "attribute": "current-item-id", "reflect": false, "defaultValue": "''" }, "interval": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u81EA\u52A8\u5207\u6362\u65F6\u95F4\u95F4\u9694" }, "attribute": "interval", "reflect": false, "defaultValue": "5000" }, "duration": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u6ED1\u52A8\u52A8\u753B\u65F6\u957F" }, "attribute": "duration", "reflect": false, "defaultValue": "500" }, "circular": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u662F\u5426\u91C7\u7528\u8854\u63A5\u6ED1\u52A8" }, "attribute": "circular", "reflect": false, "defaultValue": "false" }, "vertical": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u6ED1\u52A8\u65B9\u5411\u662F\u5426\u4E3A\u7EB5\u5411" }, "attribute": "vertical", "reflect": false, "defaultValue": "false" }, "previousMargin": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u524D\u8FB9\u8DDD\uFF0C\u53EF\u7528\u4E8E\u9732\u51FA\u524D\u4E00\u9879\u7684\u4E00\u5C0F\u90E8\u5206\uFF0C\u63A5\u53D7 px \u503C" }, "attribute": "previous-margin", "reflect": false, "defaultValue": "'0px'" }, "nextMargin": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u540E\u8FB9\u8DDD\uFF0C\u53EF\u7528\u4E8E\u9732\u51FA\u540E\u4E00\u9879\u7684\u4E00\u5C0F\u90E8\u5206\uFF0C\u63A5\u53D7 px \u503C" }, "attribute": "next-margin", "reflect": false, "defaultValue": "'0px'" }, "displayMultipleItems": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u540C\u65F6\u663E\u793A\u7684\u6ED1\u5757\u6570\u91CF" }, "attribute": "display-multiple-items", "reflect": false, "defaultValue": "1" }, "full": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u7ED9 previewImage API \u4F7F\u7528\uFF0C\u5168\u5C4F\u663E\u793A swiper" }, "attribute": "full", "reflect": false, "defaultValue": "false" }, "zoom": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "\u7ED9 previewImage API \u4F7F\u7528\uFF0C\u7F29\u653E\u652F\u6301" }, "attribute": "zoom", "reflect": false, "defaultValue": "false" } }; } static get states() { return { "swiperWrapper": {}, "swiper": {}, "isWillLoadCalled": {}, "observer": {}, "observerFirst": {}, "observerLast": {} }; } static get events() { return [{ "method": "onChange", "name": "change", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "onAnimationFinish", "name": "animationfinish", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }]; } static get elementRef() { return "el"; } static get watchers() { return [{ "propName": "current", "methodName": "watchCurrent" }, { "propName": "currentItemId", "methodName": "watchCurrentItemId" }, { "propName": "autoplay", "methodName": "watchAutoplay" }, { "propName": "duration", "methodName": "watchDuration" }, { "propName": "interval", "methodName": "watchInterval" }, { "propName": "swiperWrapper", "methodName": "watchSwiperWrapper" }, { "propName": "circular", "methodName": "watchCircular" }, { "propName": "displayMultipleItems", "methodName": "watchDisplayMultipleItems" }]; } } _Swiper_id = new WeakMap(), _Swiper_source = new WeakMap();