ソースを参照

完善文档,优化体验

songqibin 7 年 前
コミット
ab9b340220

+ 6 - 5
src/demo/scroller.vue

@@ -7,8 +7,7 @@
     <h5>示例</h5>
     <div class="scroller-container">
       <nut-scroller 
-        :on-refresh="onRefresh"
-        :on-infinite="onInfinite">
+        :onRefresh="onRefresh" :onInfinite="onInfinite">
         <div v-for="(item, index) in list" :key="index" class="content-item">{{'滚动区域的内容' + (index + 1)}}</div>
       </nut-scroller>
     </div>
@@ -31,10 +30,12 @@ export default {
     },
     onInfinite(done) {
       setTimeout(() => {
-        if (this.list && this.list.length < 35) {
-          this.list = [...this.list, ...Array(15)]
+        if (this.list && this.list.length < 30) {
+          this.list = [...this.list, ...Array(10)]
+          done(true);
+          return
         }
-        done()
+        done(false)
       }, 2000)
     }
   }

+ 62 - 0
src/package/scroller/src/module/animate.js

@@ -0,0 +1,62 @@
+
+window.requestAnimFrame = (function(){
+  return  window.requestAnimationFrame       || 
+          window.webkitRequestAnimationFrame || 
+          window.mozRequestAnimationFrame    || 
+          window.oRequestAnimationFrame      || 
+          window.msRequestAnimationFrame     || 
+          function( callback ){
+            window.setTimeout(callback, 1000 / 60);
+          };
+})();
+
+export default content => {
+
+  let global = window;
+
+  let docStyle = document.documentElement.style;
+
+  let engine;
+  if (global.opera && Object.prototype.toString.call(opera) === '[object Opera]') {
+    engine = 'presto';
+  } else if ('MozAppearance' in docStyle) {
+    engine = 'gecko';
+  } else if ('WebkitAppearance' in docStyle) {
+    engine = 'webkit';
+  } else if (typeof navigator.cpuClass === 'string') {
+    engine = 'trident';
+  }
+
+  let vendorPrefix = {
+    trident: 'ms',
+    gecko: 'Moz',
+    webkit: 'Webkit',
+    presto: 'O'
+  }[engine];
+
+  return (end, start) => {
+    if (typeof start === 'undefined') {
+      content.style[vendorPrefix + 'Transform'] = 'translate3d(0, ' + end + 'px, 0)'
+      return
+    }
+    let _end = end
+    let _start = start
+    let dis 
+    let tar 
+    let step
+    let _move = () => {
+      dis = _end - _start
+      step = dis / 10
+      tar = _start + step
+      _start = tar
+      if (Math.abs(dis - step) < 1) {
+        content.style.WebkitTransform = 'translate3d(0, ' + end + 'px, 0)'
+        return
+      }
+      content.style.WebkitTransform = 'translate3d(0, ' + tar + 'px, 0)'
+      window.requestAnimFrame(_move)
+    }
+    window.requestAnimFrame(_move)
+  }
+}
+

+ 116 - 0
src/package/scroller/src/module/scroller.js

@@ -0,0 +1,116 @@
+export default class Scroller {
+  constructor(callback, options) {
+    let _options = {
+      top : 0,
+      pullH : 0,
+      loadH: 0,
+      outerH : 0,
+      prevTop : 0,
+      startY : 0,
+      offset : 100,
+      fetching : false,
+      hasMore: true
+    }
+    this.__animate = callback
+    for (let key in _options) {
+			this[key] = _options[key];
+    }
+    for (let key in options) {
+			this[key] = options[key];
+    }
+    this.innerH = this.innerContent.clientHeight
+    this.moveY = 0
+  }
+
+  initPullToRefresh(startPullCallback, arrivalFreedCallback, freedCallback) {
+    this.pullStart = startPullCallback
+    this.arrivalFreed = arrivalFreedCallback
+    this.freed = freedCallback
+  }
+
+  initPullToInfinite(infiniteCallback) {
+    this.onInfinite = infiniteCallback
+  }
+
+  doTouchStart(touches) {
+    this.prevTop = this.top
+    this.startY = touches[0].pageY
+    this.innerH = this.innerContent.clientHeight
+    this.moveY = 0
+  }
+
+  doTouchMove(touches) {
+    if (this.fetching) return
+
+    let _moveY = touches[0].pageY - this.startY
+    this.moveY = _moveY
+   
+    let _top = this.moveY + this.prevTop
+    this.__animate(_top)
+    this.top = _top
+    this.moveY = _moveY
+    if (this.fetching) return
+
+    let isBottom = Math.abs(_top) + this.outerH > this.innerH ? true : false
+    if (_moveY > 0) {
+      if (!this.enableRefresh) return
+      _top >= this.offset ? this.arrivalFreed() : this.pullStart()
+    } else {
+      if (!isBottom || !this.hasMore || !this.enableInfinite) return
+      this.fetching = true
+      this.onInfinite()
+    }
+  }
+
+  doTouchEnd(e) {
+    this.innerH = this.innerContent.clientHeight
+    let _normalEndTop = this.outerH - this.innerH
+    let isBottom = Math.abs(this.top) + this.outerH >= this.innerH ? true : false
+    if (this.top >= this.offset) {
+      if (!this.enableRefresh) {
+        this.__animate(0, this.top) 
+        this.top = 0
+        return
+      }
+      this.__animate(this.pullH, this.top)
+      this.top = this.pullH
+      this.freed()
+      return
+    }
+    if (this.top < 0 && !isBottom) {
+      this.__animate(this.top, this.top - this.moveY)
+      return
+    }
+    if (this.top < 0 && isBottom) {
+      if (this.outerH >= this.innerH) {
+        this.__animate(0, this.top)
+        this.top = 0
+        return
+      }
+      let _h = _normalEndTop
+      if (this.fetching) {
+        _h = _normalEndTop - this.loadH
+      }
+      this.__animate(_h, this.top)
+      this.top = _h
+      return
+    }
+    this.__animate(0, this.top)
+    this.top = 0
+  }
+
+  startRefresh() {
+    this.fetching = true
+  }
+
+  finishedRefesh() {
+    this.fetching = false
+    this.__animate(0, this.top)
+    this.top = 0
+  }
+
+  finishedInfinite(hasMore) {
+    this.fetching = false
+    this.hasMore = hasMore
+  }
+}

ファイルの差分が大きいため隠しています
+ 104 - 106
src/package/scroller/src/scroller.vue


+ 7 - 4
src/view/scroller.vue

@@ -10,8 +10,7 @@
         <h6>示例</h6>
         <div class="scroller-container">
           <nut-scroller 
-            :on-refresh="onRefresh"
-            :on-infinite="onInfinite">
+            :onRefresh="onRefresh" :onInfinite="onInfinite">
             <div v-for="(item, index) in list" :key="index" class="content-item">{{'滚动区域的内容' + (index + 1)}}</div>
           </nut-scroller>
         </div>
@@ -162,8 +161,10 @@ export default {
                 setTimeout(() => {
                   if (this.list && this.list.length < 30) {
                     this.list = [...this.list, ...Array(10)]
+                    done(true);
+                    return
                   }
-                  done()
+                  done(false) // 回传没有更多数据的标识
                 }, 2000)
               }
             }
@@ -186,8 +187,10 @@ export default {
       setTimeout(() => {
         if (this.list && this.list.length < 30) {
           this.list = [...this.list, ...Array(10)]
+          done(true);
+          return
         }
-        done()
+        done(false)
       }, 2000)
     }
   }