@tarojs/components 4.0.5-alpha.6 → 4.0.5-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,7 +42,10 @@ const Swiper = class {
42
42
  this.onAnimationFinish = index.createEvent(this, "animationfinish", 7);
43
43
  _Swiper_id.set(this, INSTANCE_ID++);
44
44
  _Swiper_source.set(this, '');
45
- _Swiper_swiperResetting.set(this, false);
45
+ _Swiper_swiperResetting.set(this, false
46
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
47
+ );
48
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
46
49
  _Swiper_domChangeByOutSide.set(this, false);
47
50
  _Swiper_lastSwiperActiveIndex.set(this, 0);
48
51
  this.handleSwiperSizeDebounce = index$1.debounce(() => {
@@ -60,7 +63,16 @@ const Swiper = class {
60
63
  __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
61
64
  }
62
65
  }, 50);
66
+ this.reset = () => {
67
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
68
+ __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
69
+ this.swiper.destroy();
70
+ this.handleInit(true);
71
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
72
+ };
73
+ // 下面为方法函数
63
74
  this.getSlidersList = () => this.el.querySelectorAll('taro-swiper-item-core:not(.swiper-slide-duplicate)') || [];
75
+ // 获取是否需要手动修复 loop 的条件
64
76
  this.getNeedFixLoop = () => {
65
77
  const margins = this.parseMargin();
66
78
  const hasMargin = margins.filter(Boolean).length > 0;
@@ -71,13 +83,6 @@ const Swiper = class {
71
83
  const [, nextMargin] = /^(\d+)px/.exec(this.nextMargin) || [];
72
84
  return [parseInt(previousMargin) || 0, parseInt(nextMargin) || 0];
73
85
  };
74
- this.reset = () => {
75
- __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
76
- __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
77
- this.swiper.destroy();
78
- this.handleInit(true);
79
- __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
80
- };
81
86
  this.swiperWrapper = undefined;
82
87
  this.swiper = undefined;
83
88
  this.isWillLoadCalled = false;
@@ -183,39 +188,38 @@ const Swiper = class {
183
188
  return;
184
189
  if (!newVal)
185
190
  return;
191
+ const beforeDomOperation = () => {
192
+ __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
193
+ // 如果是由于外部子节点的变化引起的 dom 变化,需要重新初始化 swiper。
194
+ // 在初dom操作之前,需要调用 loopDestroy,把子节点的顺序恢复
195
+ this.swiper.loopDestroy();
196
+ this.swiper.params.loop = false;
197
+ };
186
198
  this.el.appendChild = (newChild) => {
187
199
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
188
200
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
189
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
190
- this.swiper.loopDestroy();
191
- this.swiper.params.loop = false;
201
+ beforeDomOperation();
192
202
  }
193
203
  return newVal.appendChild(newChild);
194
204
  };
195
205
  this.el.insertBefore = (newChild, refChild) => {
196
206
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
197
207
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
198
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
199
- this.swiper.loopDestroy();
200
- this.swiper.params.loop = false;
208
+ beforeDomOperation();
201
209
  }
202
210
  return newVal.insertBefore(newChild, refChild);
203
211
  };
204
212
  this.el.replaceChild = (newChild, oldChild) => {
205
213
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
206
214
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
207
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
208
- this.swiper.loopDestroy();
209
- this.swiper.params.loop = false;
215
+ beforeDomOperation();
210
216
  }
211
217
  return newVal.replaceChild(newChild, oldChild);
212
218
  };
213
219
  this.el.removeChild = (oldChild) => {
214
220
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
215
221
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
216
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
217
- this.swiper.loopDestroy();
218
- this.swiper.params.loop = false;
222
+ beforeDomOperation();
219
223
  }
220
224
  return newVal.removeChild(oldChild);
221
225
  };
@@ -308,6 +312,9 @@ const Swiper = class {
308
312
  },
309
313
  autoplay(e) {
310
314
  // Note: 修复 autoplay 时,切换到其他页面再切回来,autoplay 会停止的问题
315
+ // autoplay 会调用 slideTo 方法,里面会判断是否 animating,如果 animating 为 true,就会被 return
316
+ // 参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/slide/slideTo.mjs#27 27行
317
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/modules/autoplay/autoplay.mjs
311
318
  e.animating = false;
312
319
  __classPrivateFieldSet(that, _Swiper_source, 'autoplay', "f");
313
320
  }
@@ -320,7 +327,10 @@ const Swiper = class {
320
327
  };
321
328
  }
322
329
  this.swiper = new SwiperJS__default['default'](`.taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container`, options);
323
- //Note: 注释
330
+ // Note: 这里是拦截了 swiper 的 minTranslate 和 maxTranslate 方法,手动修复了 loop 模式下的 margin 问题
331
+ // 因为这两个属性会影响滑动到哪个位置进行 fixloop
332
+ // 可参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/events/onTouchMove.mjs
333
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/loop/loopFix.mjs
324
334
  if (this.getNeedFixLoop()) {
325
335
  // @ts-ignore
326
336
  const minTranslate = this.swiper.minTranslate.bind(this.swiper);
@@ -341,7 +351,8 @@ const Swiper = class {
341
351
  }
342
352
  this.swiperWrapper = this.swiper.wrapperEl;
343
353
  }
344
- //Note: 注释
354
+ // Note: loop 的时候添加 additionalSlides 可以避免循环的时候由于 loopFix 不及时,出现空白的问题。但是并不是 additionalSlides 越多越好,因为 additionalSlides 越多,如果 swiper-item 的数量不够,会导致出现 bug。
355
+ // 目前的策略是 swiper-item 的数量小于等于 5 时,不添加 additionalSlides,大于 5 小于等于 7 时,添加 1 个 additionalSlides,大于 7 时,添加 2 个 additionalSlides。
345
356
  getLoopAdditionalSlides() {
346
357
  const slidersLength = (this.getSlidersList()).length;
347
358
  if (!this.el || !this.getNeedFixLoop() || slidersLength < ONE_ADDITIONAL_SLIDES_THRESHOLD)
@@ -25,7 +25,10 @@ export class Swiper {
25
25
  constructor() {
26
26
  _Swiper_id.set(this, INSTANCE_ID++);
27
27
  _Swiper_source.set(this, '');
28
- _Swiper_swiperResetting.set(this, false);
28
+ _Swiper_swiperResetting.set(this, false
29
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
30
+ );
31
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
29
32
  _Swiper_domChangeByOutSide.set(this, false);
30
33
  _Swiper_lastSwiperActiveIndex.set(this, 0);
31
34
  this.handleSwiperSizeDebounce = debounce(() => {
@@ -43,7 +46,16 @@ export class Swiper {
43
46
  __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
44
47
  }
45
48
  }, 50);
49
+ this.reset = () => {
50
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
51
+ __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
52
+ this.swiper.destroy();
53
+ this.handleInit(true);
54
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
55
+ };
56
+ // 下面为方法函数
46
57
  this.getSlidersList = () => this.el.querySelectorAll('taro-swiper-item-core:not(.swiper-slide-duplicate)') || [];
58
+ // 获取是否需要手动修复 loop 的条件
47
59
  this.getNeedFixLoop = () => {
48
60
  const margins = this.parseMargin();
49
61
  const hasMargin = margins.filter(Boolean).length > 0;
@@ -54,13 +66,6 @@ export class Swiper {
54
66
  const [, nextMargin] = /^(\d+)px/.exec(this.nextMargin) || [];
55
67
  return [parseInt(previousMargin) || 0, parseInt(nextMargin) || 0];
56
68
  };
57
- this.reset = () => {
58
- __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
59
- __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
60
- this.swiper.destroy();
61
- this.handleInit(true);
62
- __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
63
- };
64
69
  this.swiperWrapper = undefined;
65
70
  this.swiper = undefined;
66
71
  this.isWillLoadCalled = false;
@@ -166,39 +171,38 @@ export class Swiper {
166
171
  return;
167
172
  if (!newVal)
168
173
  return;
174
+ const beforeDomOperation = () => {
175
+ __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
176
+ // 如果是由于外部子节点的变化引起的 dom 变化,需要重新初始化 swiper。
177
+ // 在初dom操作之前,需要调用 loopDestroy,把子节点的顺序恢复
178
+ this.swiper.loopDestroy();
179
+ this.swiper.params.loop = false;
180
+ };
169
181
  this.el.appendChild = (newChild) => {
170
182
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
171
183
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
172
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
173
- this.swiper.loopDestroy();
174
- this.swiper.params.loop = false;
184
+ beforeDomOperation();
175
185
  }
176
186
  return newVal.appendChild(newChild);
177
187
  };
178
188
  this.el.insertBefore = (newChild, refChild) => {
179
189
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
180
190
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
181
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
182
- this.swiper.loopDestroy();
183
- this.swiper.params.loop = false;
191
+ beforeDomOperation();
184
192
  }
185
193
  return newVal.insertBefore(newChild, refChild);
186
194
  };
187
195
  this.el.replaceChild = (newChild, oldChild) => {
188
196
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
189
197
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
190
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
191
- this.swiper.loopDestroy();
192
- this.swiper.params.loop = false;
198
+ beforeDomOperation();
193
199
  }
194
200
  return newVal.replaceChild(newChild, oldChild);
195
201
  };
196
202
  this.el.removeChild = (oldChild) => {
197
203
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
198
204
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
199
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
200
- this.swiper.loopDestroy();
201
- this.swiper.params.loop = false;
205
+ beforeDomOperation();
202
206
  }
203
207
  return newVal.removeChild(oldChild);
204
208
  };
@@ -291,6 +295,9 @@ export class Swiper {
291
295
  },
292
296
  autoplay(e) {
293
297
  // Note: 修复 autoplay 时,切换到其他页面再切回来,autoplay 会停止的问题
298
+ // autoplay 会调用 slideTo 方法,里面会判断是否 animating,如果 animating 为 true,就会被 return
299
+ // 参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/slide/slideTo.mjs#27 27行
300
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/modules/autoplay/autoplay.mjs
294
301
  e.animating = false;
295
302
  __classPrivateFieldSet(that, _Swiper_source, 'autoplay', "f");
296
303
  }
@@ -303,7 +310,10 @@ export class Swiper {
303
310
  };
304
311
  }
305
312
  this.swiper = new SwiperJS(`.taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container`, options);
306
- //Note: 注释
313
+ // Note: 这里是拦截了 swiper 的 minTranslate 和 maxTranslate 方法,手动修复了 loop 模式下的 margin 问题
314
+ // 因为这两个属性会影响滑动到哪个位置进行 fixloop
315
+ // 可参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/events/onTouchMove.mjs
316
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/loop/loopFix.mjs
307
317
  if (this.getNeedFixLoop()) {
308
318
  // @ts-ignore
309
319
  const minTranslate = this.swiper.minTranslate.bind(this.swiper);
@@ -324,7 +334,8 @@ export class Swiper {
324
334
  }
325
335
  this.swiperWrapper = this.swiper.wrapperEl;
326
336
  }
327
- //Note: 注释
337
+ // Note: loop 的时候添加 additionalSlides 可以避免循环的时候由于 loopFix 不及时,出现空白的问题。但是并不是 additionalSlides 越多越好,因为 additionalSlides 越多,如果 swiper-item 的数量不够,会导致出现 bug。
338
+ // 目前的策略是 swiper-item 的数量小于等于 5 时,不添加 additionalSlides,大于 5 小于等于 7 时,添加 1 个 additionalSlides,大于 7 时,添加 2 个 additionalSlides。
328
339
  getLoopAdditionalSlides() {
329
340
  const slidersLength = (this.getSlidersList()).length;
330
341
  if (!this.el || !this.getNeedFixLoop() || slidersLength < ONE_ADDITIONAL_SLIDES_THRESHOLD)
@@ -32,7 +32,10 @@ const Swiper = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
32
32
  this.onAnimationFinish = createEvent(this, "animationfinish", 7);
33
33
  _Swiper_id.set(this, INSTANCE_ID++);
34
34
  _Swiper_source.set(this, '');
35
- _Swiper_swiperResetting.set(this, false);
35
+ _Swiper_swiperResetting.set(this, false
36
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
37
+ );
38
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
36
39
  _Swiper_domChangeByOutSide.set(this, false);
37
40
  _Swiper_lastSwiperActiveIndex.set(this, 0);
38
41
  this.handleSwiperSizeDebounce = debounce(() => {
@@ -50,7 +53,16 @@ const Swiper = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
50
53
  __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
51
54
  }
52
55
  }, 50);
56
+ this.reset = () => {
57
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
58
+ __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
59
+ this.swiper.destroy();
60
+ this.handleInit(true);
61
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
62
+ };
63
+ // 下面为方法函数
53
64
  this.getSlidersList = () => this.el.querySelectorAll('taro-swiper-item-core:not(.swiper-slide-duplicate)') || [];
65
+ // 获取是否需要手动修复 loop 的条件
54
66
  this.getNeedFixLoop = () => {
55
67
  const margins = this.parseMargin();
56
68
  const hasMargin = margins.filter(Boolean).length > 0;
@@ -61,13 +73,6 @@ const Swiper = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
61
73
  const [, nextMargin] = /^(\d+)px/.exec(this.nextMargin) || [];
62
74
  return [parseInt(previousMargin) || 0, parseInt(nextMargin) || 0];
63
75
  };
64
- this.reset = () => {
65
- __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
66
- __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
67
- this.swiper.destroy();
68
- this.handleInit(true);
69
- __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
70
- };
71
76
  this.swiperWrapper = undefined;
72
77
  this.swiper = undefined;
73
78
  this.isWillLoadCalled = false;
@@ -173,39 +178,38 @@ const Swiper = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
173
178
  return;
174
179
  if (!newVal)
175
180
  return;
181
+ const beforeDomOperation = () => {
182
+ __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
183
+ // 如果是由于外部子节点的变化引起的 dom 变化,需要重新初始化 swiper。
184
+ // 在初dom操作之前,需要调用 loopDestroy,把子节点的顺序恢复
185
+ this.swiper.loopDestroy();
186
+ this.swiper.params.loop = false;
187
+ };
176
188
  this.el.appendChild = (newChild) => {
177
189
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
178
190
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
179
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
180
- this.swiper.loopDestroy();
181
- this.swiper.params.loop = false;
191
+ beforeDomOperation();
182
192
  }
183
193
  return newVal.appendChild(newChild);
184
194
  };
185
195
  this.el.insertBefore = (newChild, refChild) => {
186
196
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
187
197
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
188
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
189
- this.swiper.loopDestroy();
190
- this.swiper.params.loop = false;
198
+ beforeDomOperation();
191
199
  }
192
200
  return newVal.insertBefore(newChild, refChild);
193
201
  };
194
202
  this.el.replaceChild = (newChild, oldChild) => {
195
203
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
196
204
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
197
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
198
- this.swiper.loopDestroy();
199
- this.swiper.params.loop = false;
205
+ beforeDomOperation();
200
206
  }
201
207
  return newVal.replaceChild(newChild, oldChild);
202
208
  };
203
209
  this.el.removeChild = (oldChild) => {
204
210
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
205
211
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
206
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
207
- this.swiper.loopDestroy();
208
- this.swiper.params.loop = false;
212
+ beforeDomOperation();
209
213
  }
210
214
  return newVal.removeChild(oldChild);
211
215
  };
@@ -298,6 +302,9 @@ const Swiper = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
298
302
  },
299
303
  autoplay(e) {
300
304
  // Note: 修复 autoplay 时,切换到其他页面再切回来,autoplay 会停止的问题
305
+ // autoplay 会调用 slideTo 方法,里面会判断是否 animating,如果 animating 为 true,就会被 return
306
+ // 参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/slide/slideTo.mjs#27 27行
307
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/modules/autoplay/autoplay.mjs
301
308
  e.animating = false;
302
309
  __classPrivateFieldSet(that, _Swiper_source, 'autoplay', "f");
303
310
  }
@@ -310,7 +317,10 @@ const Swiper = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
310
317
  };
311
318
  }
312
319
  this.swiper = new SwiperJS(`.taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container`, options);
313
- //Note: 注释
320
+ // Note: 这里是拦截了 swiper 的 minTranslate 和 maxTranslate 方法,手动修复了 loop 模式下的 margin 问题
321
+ // 因为这两个属性会影响滑动到哪个位置进行 fixloop
322
+ // 可参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/events/onTouchMove.mjs
323
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/loop/loopFix.mjs
314
324
  if (this.getNeedFixLoop()) {
315
325
  // @ts-ignore
316
326
  const minTranslate = this.swiper.minTranslate.bind(this.swiper);
@@ -331,7 +341,8 @@ const Swiper = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
331
341
  }
332
342
  this.swiperWrapper = this.swiper.wrapperEl;
333
343
  }
334
- //Note: 注释
344
+ // Note: loop 的时候添加 additionalSlides 可以避免循环的时候由于 loopFix 不及时,出现空白的问题。但是并不是 additionalSlides 越多越好,因为 additionalSlides 越多,如果 swiper-item 的数量不够,会导致出现 bug。
345
+ // 目前的策略是 swiper-item 的数量小于等于 5 时,不添加 additionalSlides,大于 5 小于等于 7 时,添加 1 个 additionalSlides,大于 7 时,添加 2 个 additionalSlides。
335
346
  getLoopAdditionalSlides() {
336
347
  const slidersLength = (this.getSlidersList()).length;
337
348
  if (!this.el || !this.getNeedFixLoop() || slidersLength < ONE_ADDITIONAL_SLIDES_THRESHOLD)
@@ -34,7 +34,10 @@ const Swiper = class {
34
34
  this.onAnimationFinish = createEvent(this, "animationfinish", 7);
35
35
  _Swiper_id.set(this, INSTANCE_ID++);
36
36
  _Swiper_source.set(this, '');
37
- _Swiper_swiperResetting.set(this, false);
37
+ _Swiper_swiperResetting.set(this, false
38
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
39
+ );
40
+ // dom 变化是否由外部引起,因为 swiper 的循环模式也会引起 dom 的变化。如果不是由外部引起的 dom 变化,就不需要重新初始化 swiper
38
41
  _Swiper_domChangeByOutSide.set(this, false);
39
42
  _Swiper_lastSwiperActiveIndex.set(this, 0);
40
43
  this.handleSwiperSizeDebounce = debounce(() => {
@@ -52,7 +55,16 @@ const Swiper = class {
52
55
  __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
53
56
  }
54
57
  }, 50);
58
+ this.reset = () => {
59
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
60
+ __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
61
+ this.swiper.destroy();
62
+ this.handleInit(true);
63
+ __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
64
+ };
65
+ // 下面为方法函数
55
66
  this.getSlidersList = () => this.el.querySelectorAll('taro-swiper-item-core:not(.swiper-slide-duplicate)') || [];
67
+ // 获取是否需要手动修复 loop 的条件
56
68
  this.getNeedFixLoop = () => {
57
69
  const margins = this.parseMargin();
58
70
  const hasMargin = margins.filter(Boolean).length > 0;
@@ -63,13 +75,6 @@ const Swiper = class {
63
75
  const [, nextMargin] = /^(\d+)px/.exec(this.nextMargin) || [];
64
76
  return [parseInt(previousMargin) || 0, parseInt(nextMargin) || 0];
65
77
  };
66
- this.reset = () => {
67
- __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
68
- __classPrivateFieldSet(this, _Swiper_lastSwiperActiveIndex, this.swiper.realIndex, "f");
69
- this.swiper.destroy();
70
- this.handleInit(true);
71
- __classPrivateFieldSet(this, _Swiper_swiperResetting, false, "f");
72
- };
73
78
  this.swiperWrapper = undefined;
74
79
  this.swiper = undefined;
75
80
  this.isWillLoadCalled = false;
@@ -175,39 +180,38 @@ const Swiper = class {
175
180
  return;
176
181
  if (!newVal)
177
182
  return;
183
+ const beforeDomOperation = () => {
184
+ __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
185
+ // 如果是由于外部子节点的变化引起的 dom 变化,需要重新初始化 swiper。
186
+ // 在初dom操作之前,需要调用 loopDestroy,把子节点的顺序恢复
187
+ this.swiper.loopDestroy();
188
+ this.swiper.params.loop = false;
189
+ };
178
190
  this.el.appendChild = (newChild) => {
179
191
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
180
192
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
181
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
182
- this.swiper.loopDestroy();
183
- this.swiper.params.loop = false;
193
+ beforeDomOperation();
184
194
  }
185
195
  return newVal.appendChild(newChild);
186
196
  };
187
197
  this.el.insertBefore = (newChild, refChild) => {
188
198
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
189
199
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
190
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
191
- this.swiper.loopDestroy();
192
- this.swiper.params.loop = false;
200
+ beforeDomOperation();
193
201
  }
194
202
  return newVal.insertBefore(newChild, refChild);
195
203
  };
196
204
  this.el.replaceChild = (newChild, oldChild) => {
197
205
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
198
206
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
199
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
200
- this.swiper.loopDestroy();
201
- this.swiper.params.loop = false;
207
+ beforeDomOperation();
202
208
  }
203
209
  return newVal.replaceChild(newChild, oldChild);
204
210
  };
205
211
  this.el.removeChild = (oldChild) => {
206
212
  __classPrivateFieldSet(this, _Swiper_swiperResetting, true, "f");
207
213
  if (!__classPrivateFieldGet(this, _Swiper_domChangeByOutSide, "f") && this.circular) {
208
- __classPrivateFieldSet(this, _Swiper_domChangeByOutSide, true, "f");
209
- this.swiper.loopDestroy();
210
- this.swiper.params.loop = false;
214
+ beforeDomOperation();
211
215
  }
212
216
  return newVal.removeChild(oldChild);
213
217
  };
@@ -300,6 +304,9 @@ const Swiper = class {
300
304
  },
301
305
  autoplay(e) {
302
306
  // Note: 修复 autoplay 时,切换到其他页面再切回来,autoplay 会停止的问题
307
+ // autoplay 会调用 slideTo 方法,里面会判断是否 animating,如果 animating 为 true,就会被 return
308
+ // 参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/slide/slideTo.mjs#27 27行
309
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/modules/autoplay/autoplay.mjs
303
310
  e.animating = false;
304
311
  __classPrivateFieldSet(that, _Swiper_source, 'autoplay', "f");
305
312
  }
@@ -312,7 +319,10 @@ const Swiper = class {
312
319
  };
313
320
  }
314
321
  this.swiper = new SwiperJS(`.taro-swiper-${__classPrivateFieldGet(this, _Swiper_id, "f")} > .swiper-container`, options);
315
- //Note: 注释
322
+ // Note: 这里是拦截了 swiper 的 minTranslate 和 maxTranslate 方法,手动修复了 loop 模式下的 margin 问题
323
+ // 因为这两个属性会影响滑动到哪个位置进行 fixloop
324
+ // 可参考源码:https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/events/onTouchMove.mjs
325
+ // https://github.com/nolimits4web/swiper/blob/v11.1.0/src/core/loop/loopFix.mjs
316
326
  if (this.getNeedFixLoop()) {
317
327
  // @ts-ignore
318
328
  const minTranslate = this.swiper.minTranslate.bind(this.swiper);
@@ -333,7 +343,8 @@ const Swiper = class {
333
343
  }
334
344
  this.swiperWrapper = this.swiper.wrapperEl;
335
345
  }
336
- //Note: 注释
346
+ // Note: loop 的时候添加 additionalSlides 可以避免循环的时候由于 loopFix 不及时,出现空白的问题。但是并不是 additionalSlides 越多越好,因为 additionalSlides 越多,如果 swiper-item 的数量不够,会导致出现 bug。
347
+ // 目前的策略是 swiper-item 的数量小于等于 5 时,不添加 additionalSlides,大于 5 小于等于 7 时,添加 1 个 additionalSlides,大于 7 时,添加 2 个 additionalSlides。
337
348
  getLoopAdditionalSlides() {
338
349
  const slidersLength = (this.getSlidersList()).length;
339
350
  if (!this.el || !this.getNeedFixLoop() || slidersLength < ONE_ADDITIONAL_SLIDES_THRESHOLD)