@dolphinweex/weex-vue-render 0.2.26 → 0.2.28

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.
Files changed (2) hide show
  1. package/dist/index.common.js +198 -109
  2. package/package.json +1 -1
@@ -5930,7 +5930,7 @@ var scrollable$1 = {
5930
5930
  this._loadmoreReset = false;
5931
5931
  var el = this.$el;
5932
5932
  if (el) {
5933
- weex.utils.dispatchNativeEvent(el, 'loadmore');
5933
+ weex.utils.dispatchNativeEvent(el, 'loading');
5934
5934
  }
5935
5935
  }
5936
5936
  }
@@ -7443,7 +7443,6 @@ var slideMixin = {
7443
7443
  this._clones = [];
7444
7444
  this.innerOffset = 0;
7445
7445
  this._indicator = null;
7446
- this.cloneIndex = this.frameCount > 1 ? Boolean(this.infinite) : 0 //需要减或者加去克隆下标
7447
7446
  },
7448
7447
 
7449
7448
  beforeUpdate: function beforeUpdate () {
@@ -7499,7 +7498,7 @@ var slideMixin = {
7499
7498
 
7500
7499
  mounted: function mounted () {
7501
7500
  this._getWrapperSize();
7502
- this._slideTo(this.currentIndex + this.cloneIndex);
7501
+ this._slideTo(this.currentIndex);
7503
7502
  weex.utils.fireLazyload(this.$el, true);
7504
7503
  },
7505
7504
 
@@ -7532,34 +7531,11 @@ var slideMixin = {
7532
7531
  }, [vnode])
7533
7532
  });
7534
7533
 
7535
- if (this.infinite && cells.length > 1) {
7536
- // 克隆第一个和最后一个有效节点
7537
- const cloneFirst = () => {
7538
- const first = cells[0];
7539
- return first ? createElement('li', {
7540
- staticClass: "weex-slider-cell weex-ct clone-cell",
7541
- key: 'clone-first'
7542
- }, [first.children || first.componentOptions.children]) : null
7543
- };
7544
-
7545
- const cloneLast = () => {
7546
- const last = cells[cells.length - 1];
7547
- return last ? createElement('li', {
7548
- staticClass: "weex-slider-cell weex-ct clone-cell",
7549
- key: 'clone-last'
7550
- }, [last.children || last.componentOptions.children]) : null
7551
- };
7552
- const lastClone = cloneLast();
7553
- const firstClone = cloneFirst();
7554
-
7555
- if (firstClone && lastClone) {
7556
- cells = [lastClone].concat(cells).concat([firstClone]);
7557
- }
7558
- }
7534
+
7559
7535
  if (indicatorVnode) {
7560
7536
  indicatorVnode.data.attrs = indicatorVnode.data.attrs || {};
7561
7537
  indicatorVnode.data.attrs.count = cells.length - (this.infinite ? 2 : 0 ); // 显示实际数量
7562
- indicatorVnode.data.attrs.active = this.currentIndex - this.cloneIndex;
7538
+ indicatorVnode.data.attrs.active = this.currentIndex ;
7563
7539
  this._indicator = indicatorVnode;
7564
7540
  }
7565
7541
  return cells
@@ -7624,12 +7600,20 @@ var slideMixin = {
7624
7600
  if (this.frameCount <= 0) {
7625
7601
  return;
7626
7602
  }
7603
+ //一张图片无需滚动操作
7604
+ if (this.frameCount <= 1) {
7605
+ this.currentIndex = 0;
7606
+ this._preIndex = 0;
7607
+ return;
7608
+ }
7609
+ // 非无限轮播的边界处理
7627
7610
  if (!this.infinite || this.infinite === 'false') {
7628
7611
  if (index === -1 || index > (this.frameCount - 1)) {
7629
7612
  this._slideTo(this.currentIndex);
7630
7613
  return;
7631
7614
  }
7632
7615
  }
7616
+
7633
7617
  if (!this._preIndex && this._preIndex !== 0) {
7634
7618
  this._preIndex = this.currentIndex || 0;
7635
7619
  }
@@ -7639,98 +7623,163 @@ var slideMixin = {
7639
7623
  }
7640
7624
  this._sliding = true;
7641
7625
 
7642
- var newIndex = this._normalizeIndex(index);
7643
7626
  var inner = this.$refs.inner;
7644
7627
  var step = this._step = this.frameCount <= 1 ? 0 : this._preIndex - index;
7645
7628
 
7646
7629
  if (inner) {
7647
7630
  this._prepareNodes();
7648
- var translate = weex.utils.getTransformObj(inner).translate;
7649
- var match = translate && translate.match(/translate[^(]+\(([+-\d.]+)/);
7650
- var innerX = parseFloat(inner.style.left);
7631
+ var innerX = parseFloat(inner.style.left) || 0;
7651
7632
  var dist = innerX - this.innerOffset + step;
7652
- this.innerOffset += step * this._wrapperWidth;
7653
7633
 
7654
- // 克隆处理:先执行正常动画到克隆的最后一张,再瞬间跳回真实的第一张
7655
- if (this.frameCount > 1 && this.infinite && index >= this.frameCount - 1) {
7656
- // 先滑到克隆的 `第一张`
7657
- newIndex = this.frameCount - 1;
7658
- this.innerOffset = -newIndex * this._wrapperWidth;
7634
+ // 处理无限轮播的边界情况 将目标元素先定位到目的地 动画结束后再回归原位
7635
+ if (this.infinite && this.infinite !== 'false') {
7636
+ if (index < 0) {
7637
+ // 从第一张向左滑
7638
+ var lastIndex = this.frameCount - 1;
7639
+
7640
+ // 先将最后一张放到左侧
7641
+ var lastNode = this._cells[lastIndex].elm;
7642
+ lastNode.style.position = 'absolute';
7643
+ lastNode.style.left = `-${this._wrapperWidth}px`;
7644
+ lastNode.style.opacity = '1';
7645
+ lastNode.style.zIndex = '10';
7646
+ // 执行向左滑动动画
7659
7647
  inner.style.transition = `left ${TRANSITION_TIME / 1000}s ease-in-out`;
7648
+ this.innerOffset += this._wrapperWidth;
7660
7649
  inner.style.left = `${this.innerOffset}px`;
7661
- newIndex = 1; // 视觉上显示 `第一张`
7662
7650
 
7663
- // 等待动画完成后瞬间跳到 `第一张`
7651
+ // 动画结束后第一张在充值回原先位置
7664
7652
  setTimeout(() => {
7665
7653
  inner.style.transition = 'none';
7666
- this.innerOffset = -this._wrapperWidth; // 瞬间跳到 `第一张`
7654
+ lastNode.style.position = '';
7655
+ lastNode.style.left = '';
7656
+ this.innerOffset = -lastIndex * this._wrapperWidth;
7667
7657
  inner.style.left = `${this.innerOffset}px`;
7658
+
7659
+ setTimeout(() => {
7660
+ inner.style.transition = `left ${TRANSITION_TIME / 1000}s ease-in-out`;
7661
+ }, 50);
7668
7662
  }, TRANSITION_TIME);
7669
- } else if (this.frameCount > 1 && this.infinite && index <= 0) {
7670
- // 先滑到克隆的 `最后一张`
7671
- newIndex = 0;
7672
- this.innerOffset = -newIndex * this._wrapperWidth;
7663
+
7664
+ index = lastIndex;
7665
+ } else if (index >= this.frameCount) {
7666
+ // 从最后一张向右滑
7667
+ // 克隆第一张图片并放置在适当位置
7668
+ var firstNode = this._cells[0].elm;
7669
+ var cloneNode = firstNode.cloneNode(true);
7670
+ cloneNode.style.position = 'absolute';
7671
+ cloneNode.style.left = `${this.frameCount * this._wrapperWidth}px`;
7672
+ cloneNode.style.width = `${this._wrapperWidth}px`;
7673
+ cloneNode.style.zIndex = '10';
7674
+ inner.appendChild(cloneNode);
7675
+
7676
+ // 执行向右滑动动画
7673
7677
  inner.style.transition = `left ${TRANSITION_TIME / 1000}s ease-in-out`;
7678
+ this.innerOffset -= this._wrapperWidth;
7674
7679
  inner.style.left = `${this.innerOffset}px`;
7675
- newIndex = this.frameCount - 2; // 视觉上显示 `最后一张`
7676
7680
 
7677
- // 等待动画完成后瞬间跳到 `最后一张`
7681
+ // 动画结束后重置位置
7678
7682
  setTimeout(() => {
7683
+ // 移除过渡效果
7679
7684
  inner.style.transition = 'none';
7680
- this.innerOffset = -(this.frameCount - 2) * this._wrapperWidth; // 瞬间跳到 `最后一张`
7681
- inner.style.left = `${this.innerOffset}px`;
7685
+
7686
+ // 移除克隆节点
7687
+ if (cloneNode.parentNode) {
7688
+ inner.removeChild(cloneNode);
7689
+ }
7690
+
7691
+ // 重置位置到第一张
7692
+ this.innerOffset = 0;
7693
+ inner.style.left = '0px';
7694
+
7695
+ // 短暂延迟后恢复过渡效果
7696
+ setTimeout(() => {
7697
+ inner.style.transition = `left ${TRANSITION_TIME / 1000}s ease-in-out`;
7698
+ }, 50);
7682
7699
  }, TRANSITION_TIME);
7683
7700
 
7701
+ index = 0;
7684
7702
  } else {
7685
7703
  // 正常切换
7686
- this.innerOffset = -newIndex * this._wrapperWidth;
7704
+ this.innerOffset = -index * this._wrapperWidth;
7705
+ inner.style.transition = `left ${TRANSITION_TIME / 1000}s ease-in-out`;
7706
+ inner.style.left = `${this.innerOffset}px`;
7707
+ }
7708
+ } else {
7709
+ // 非无限轮播的正常切换
7710
+ this.innerOffset = -index * this._wrapperWidth;
7687
7711
  inner.style.transition = `left ${TRANSITION_TIME / 1000}s ease-in-out`;
7688
7712
  inner.style.left = `${this.innerOffset}px`;
7689
7713
  }
7690
7714
 
7691
- // 触发事件
7715
+ // 触发滚动事件
7692
7716
  if (!isTouchScroll) {
7693
7717
  this._emitScrollEvent('scrollstart');
7694
7718
  }
7695
- setTimeout(function () {
7696
- this$1._throttleEmitScroll(dist, function () {
7719
+
7720
+ setTimeout(() => {
7721
+ this$1._throttleEmitScroll(dist, () => {
7697
7722
  this$1._emitScrollEvent('scrollend');
7698
7723
  });
7699
7724
  }, THROTTLE_SCROLL_TIME);
7700
7725
 
7701
7726
  this._loopShowNodes(step);
7702
7727
 
7703
- setTimeout(function () {
7728
+ setTimeout(() => {
7704
7729
  if (this$1.isNeighbor) {
7705
7730
  this$1._setNeighbors();
7706
7731
  }
7707
7732
 
7708
- setTimeout(function () {
7709
- inner.style.webkitTransition = '';
7710
- inner.style.mozTransition = '';
7733
+ setTimeout(() => {
7711
7734
  inner.style.transition = '';
7712
7735
  for (var i = this$1._showStartIdx; i <= this$1._showEndIdx; i++) {
7713
7736
  var node = this$1._showNodes[i];
7714
- if (!node) {continue;}
7737
+ if (!node) continue;
7715
7738
  var elm = node.firstElementChild;
7716
- if (!elm) {continue;}
7717
- elm.style.webkitTransition = '';
7718
- elm.style.mozTransition = '';
7739
+ if (!elm) continue;
7719
7740
  elm.style.transition = '';
7720
7741
  }
7721
- this$1._rearrangeNodes(newIndex);
7742
+ this$1._rearrangeNodes(index);
7722
7743
  }, NEIGHBOR_SCALE_TIME);
7723
7744
  }, TRANSITION_TIME);
7724
7745
  }
7725
7746
 
7726
- if (newIndex !== this._preIndex) {
7747
+ if (index !== this._preIndex) {
7727
7748
  weex.utils.dispatchNativeEvent(this.$el, 'change', {
7728
- index: newIndex - this.cloneIndex
7749
+ index: index
7729
7750
  });
7730
7751
  }
7752
+
7753
+ this.currentIndex = index;
7754
+ this._preIndex = index;
7755
+ },
7756
+ // 优化_prepareNodes方法以支持无缝切换
7757
+ _prepareNodes: function _prepareNodes() {
7758
+ var step = this._step;
7759
+ if (!this._inited) {
7760
+ this._initNodes();
7761
+ this._inited = true;
7762
+ this._showNodes = {};
7763
+ }
7731
7764
 
7732
- this.currentIndex = newIndex;
7733
- this._preIndex = newIndex;
7765
+ if (this.frameCount <= 1) {
7766
+ this._showStartIdx = this._showEndIdx = 0;
7767
+ var node = this._cells[0].elm;
7768
+ node.style.opacity = 1;
7769
+ node.index = 0;
7770
+ this._showNodes[0] = node;
7771
+ node._inShow = true;
7772
+ node._showIndex = 0;
7773
+ return;
7774
+ }
7775
+
7776
+ // 计算需要显示的节点范围,确保边界切换时有足够的节点
7777
+ var showCount = this._showCount = Math.abs(step) + 3;
7778
+ this._showStartIdx = step <= 0 ? -1 : 2 - showCount;
7779
+ this._showEndIdx = step <= 0 ? showCount - 2 : 1;
7780
+
7781
+ this._clearNodesOffset();
7782
+ this._positionNodes(this._showStartIdx, this._showEndIdx, step);
7734
7783
  },
7735
7784
 
7736
7785
  _clearNodesOffset: function _clearNodesOffset () {
@@ -7768,31 +7817,32 @@ var slideMixin = {
7768
7817
  this._showEndIdx += step;
7769
7818
  },
7770
7819
 
7771
- _prepareNodes: function _prepareNodes () {
7772
- // test if the next slide towards the direction exists.
7773
- // e.g. currentIndex 0 -> 1: should prepare 4 slides: -1, 0, 1, 2
7774
- // if not, translate a node to here, or just clone it.
7820
+ _prepareNodes: function _prepareNodes() {
7775
7821
  var step = this._step;
7776
7822
  if (!this._inited) {
7777
7823
  this._initNodes();
7778
7824
  this._inited = true;
7779
7825
  this._showNodes = {};
7780
7826
  }
7827
+
7828
+ // 单张图片特殊处理
7781
7829
  if (this.frameCount <= 1) {
7782
7830
  this._showStartIdx = this._showEndIdx = 0;
7783
7831
  var node = this._cells[0].elm;
7784
7832
  node.style.opacity = 1;
7785
- // node.style.zIndex = 99;
7786
7833
  node.index = 0;
7787
7834
  this._showNodes[0] = node;
7788
7835
  node._inShow = true;
7789
7836
  node._showIndex = 0;
7790
- return
7837
+ return;
7791
7838
  }
7792
7839
 
7840
+ // 计算需要显示的节点范围
7793
7841
  var showCount = this._showCount = Math.abs(step) + 3;
7794
7842
  this._showStartIdx = step <= 0 ? -1 : 2 - showCount;
7795
7843
  this._showEndIdx = step <= 0 ? showCount - 2 : 1;
7844
+
7845
+ // 清理并更新节点位置
7796
7846
  this._clearNodesOffset();
7797
7847
  this._positionNodes(this._showStartIdx, this._showEndIdx, step);
7798
7848
  },
@@ -8070,6 +8120,9 @@ var slideMixin = {
8070
8120
  },
8071
8121
 
8072
8122
  _handleTouchStart: function _handleTouchStart (event) {
8123
+ if (!this.scrollable) {
8124
+ return // 🚫 禁止滚动行为
8125
+ }
8073
8126
  var touch = event.changedTouches[0];
8074
8127
  this._stopAutoPlay();
8075
8128
  var inner = this.$refs.inner;
@@ -8112,7 +8165,43 @@ var slideMixin = {
8112
8165
  if (isV) {
8113
8166
  return
8114
8167
  }
8115
-
8168
+ // 判断是否到达边界,决定是否放行事件
8169
+ const isLeftSwipe = offsetX < 0;
8170
+ const isRightSwipe = offsetX > 0;
8171
+ const atFirst = this._preIndex === 0;
8172
+ const atLast = this._preIndex === this.frameCount - 1;
8173
+ //修改自动轮播或者无缝轮播边界滚动的过渡动画
8174
+ if (this.infinite && this.infinite !== 'false') {
8175
+ var inner = this.$refs.inner;
8176
+ if (inner && ((atFirst && isRightSwipe) || (atLast && isLeftSwipe))) {
8177
+ if (!tp.boundaryHandled) {
8178
+ tp.boundaryHandled = true;
8179
+ if (atFirst && isRightSwipe) {
8180
+ // 从第一张向右滑到最后一张
8181
+ var lastIndex = this.frameCount - 1;
8182
+ var lastNode = this._cells[lastIndex].elm;
8183
+ lastNode.style.position = 'absolute';
8184
+ lastNode.style.left = `-${this._wrapperWidth}px`;
8185
+ lastNode.style.opacity = '1';
8186
+ lastNode.style.zIndex = '10';
8187
+ } else if (atLast && isLeftSwipe) {
8188
+ // 从最后一张向左滑到第一张
8189
+ var firstNode = this._cells[0].elm;
8190
+ var cloneNode = firstNode.cloneNode(true);
8191
+ cloneNode.style.position = 'absolute';
8192
+ cloneNode.style.left = `${this.frameCount * this._wrapperWidth}px`;
8193
+ cloneNode.style.width = `${this._wrapperWidth}px`;
8194
+ cloneNode.style.zIndex = '10';
8195
+ inner.appendChild(cloneNode);
8196
+ tp.cloneNode = cloneNode;
8197
+ }
8198
+ }
8199
+ }
8200
+ }
8201
+ if (!this.infinite && !this.autoPlay && ((atLast && isLeftSwipe) || (atFirst && isRightSwipe))) {
8202
+ // ✅ 如果是边界并继续滑动,就放手,不拦截
8203
+ return;
8204
+ }
8116
8205
  if (this._sliding) {
8117
8206
  event.stopPropagation();
8118
8207
  return
@@ -8130,7 +8219,7 @@ var slideMixin = {
8130
8219
 
8131
8220
  touchSliderInstance = inner;
8132
8221
 
8133
- if (!this.autoPlay) {
8222
+ if (!this.autoPlay && !this.infinite) {
8134
8223
  // 如果不是自动播放,则当滚动到最后一页时,offsetX不能 < 0
8135
8224
  // 如果不是自动播放,则当滚动到第一页时,offsetX不能 > 0
8136
8225
  if (this._preIndex == this.frameCount - 1) {
@@ -10037,49 +10126,49 @@ function detectEvents () {
10037
10126
  detectEvents();
10038
10127
 
10039
10128
  function transitionOnce (vnode, config, callback) {
10040
- var nextFrame = utils$2.nextFrame;
10041
- var toCSSText = utils$2.toCSSText;
10042
- var styleObject2rem = utils$2.styleObject2rem;
10043
- var isArray = utils$2.isArray;
10129
+ var nextFrame = utils$2.nextFrame;
10130
+ var toCSSText = utils$2.toCSSText;
10131
+ var styleObject2rem = utils$2.styleObject2rem;
10132
+ var isArray = utils$2.isArray;
10044
10133
 
10045
- if (isArray(vnode)) {
10046
- vnode = vnode[0];
10047
- }
10134
+ if (isArray(vnode)) {
10135
+ vnode = vnode[0];
10136
+ }
10048
10137
 
10049
- var duration = config.duration || 0; // ms
10050
- var timing = config.timingFunction || 'linear';
10051
- var delay = config.delay || 0; // ms
10138
+ var duration = config.duration || 100; // ms
10139
+ var timing = config.timingFunction || 'linear';
10140
+ var delay = config.delay || 0; // ms
10052
10141
 
10053
- // TODO: parse transition properties
10054
- var transitionValue = "all " + duration + "ms " + timing + " " + delay + "ms";
10142
+ // TODO: parse transition properties
10143
+ var transitionValue = "all " + duration + "ms " + timing + " " + delay + "ms";
10055
10144
 
10056
- var dom = vnode instanceof HTMLElement ? vnode : vnode.$el;
10057
- // trigger image lazyloading by force.
10058
- dom && weex.utils.fireLazyload(dom, true);
10145
+ var dom = vnode instanceof HTMLElement ? vnode : vnode.$el;
10146
+ // trigger image lazyloading by force.
10147
+ dom && weex.utils.fireLazyload(dom, true);
10059
10148
 
10060
- var transitionEndHandler = function (event) {
10061
- event && event.stopPropagation();
10149
+ var transitionEndHandler = function (event) {
10150
+ event && event.stopPropagation();
10151
+ if (endEvent) {
10152
+ dom.removeEventListener(endEvent, transitionEndHandler);
10153
+ dom.style[styleName] = '';
10154
+ }
10155
+ setTimeout(()=>{
10156
+ callback(); //解决嵌套animation的时候 duration过小时会出现瞬间执行完毕的问题
10157
+ })
10158
+ };
10062
10159
  if (endEvent) {
10063
- dom.removeEventListener(endEvent, transitionEndHandler);
10064
- dom.style[styleName] = '';
10065
- }
10066
- setTimeout(()=>{
10067
- callback(); //解决嵌套animation的时候 duration过小时会出现瞬间执行完毕的问题
10068
- })
10069
- };
10070
- if (endEvent) {
10071
- dom.style[styleName] = transitionValue;
10072
- dom.addEventListener(endEvent, transitionEndHandler);
10073
- }
10074
- nextFrame(function () {
10075
- // 修改 transform:translate让它支持传3个参数,且第三个参数无效
10076
- if (config.styles["transform"]) {
10077
- config.styles["transform"] = config.styles["transform"].replace(/(translate\([^,]+,[^,]+),[^)]+\)/, '$1)')
10160
+ dom.style[styleName] = transitionValue;
10161
+ dom.addEventListener(endEvent, transitionEndHandler);
10078
10162
  }
10163
+ nextFrame(function () {
10164
+ // 修改 transform:translate让它支持传3个参数,且第三个参数无效
10165
+ if (config.styles["transform"]) {
10166
+ config.styles["transform"] = config.styles["transform"].replace(/(translate\([^,]+,[^,]+),[^)]+\)/, '$1)')
10167
+ }
10079
10168
 
10080
- dom.style.cssText
10081
- += toCSSText(styleObject2rem(config.styles, DESIGN_ROOT_VALUE) || {});
10082
- });
10169
+ dom.style.cssText
10170
+ += toCSSText(styleObject2rem(config.styles, DESIGN_ROOT_VALUE) || {});
10171
+ });
10083
10172
  }
10084
10173
 
10085
10174
  var animation = {
package/package.json CHANGED
@@ -49,5 +49,5 @@
49
49
  "type": "git",
50
50
  "url": "git+ssh://git@github.com/weexteam/weex-vue-render.git"
51
51
  },
52
- "version": "0.2.26"
52
+ "version": "0.2.28"
53
53
  }