Browse Source

upd:优化slider和range组件拖动性能

Frans 6 years ago
parent
commit
6b0d8d9469
3 changed files with 60 additions and 23 deletions
  1. 20 10
      src/packages/range/movebar.vue
  2. 28 13
      src/packages/slider/slider.vue
  3. 12 0
      src/utils/raf.js

+ 20 - 10
src/packages/range/movebar.vue

@@ -15,7 +15,7 @@
     </div>
 </template>
 <script>
-
+import requestAniFrame from '../../utils/raf.js';
 export default {
   name: "nut-range-bar",
   props: {
@@ -42,7 +42,8 @@ export default {
   data() {
     return {
       box: null,
-      posi: 0
+      posi: 0,
+      scheduledAnimationFrame:false
     };
   },
   watch: {
@@ -52,17 +53,26 @@ export default {
   },
   methods: {
     onTouchStart(event) {
-      event.preventDefault();
+      if (event.cancelable) {
+        event.preventDefault();
+      }
       this.$emit('update:ani', true);
     },
     onTouchMove(event) {
-      event.preventDefault();
-      const evt = event.touches[0];
-      const pageScrollLeft =
-        document.documentElement.scrollLeft || document.body.scrollLeft;
-      this.boxLeft = this.box.getBoundingClientRect().left;
-      const posi = evt.pageX - this.boxLeft - pageScrollLeft;
-      this.setPosi(posi);
+      if (event.cancelable) {
+        event.preventDefault();
+      }
+      if (this.scheduledAnimationFrame) return;
+      this.scheduledAnimationFrame = true;
+      requestAniFrame(() => {
+          this.scheduledAnimationFrame = false;
+          const evt = event.touches[0];
+          const pageScrollLeft =
+            document.documentElement.scrollLeft || document.body.scrollLeft;
+          this.boxLeft = this.box.getBoundingClientRect().left;
+          const posi = evt.pageX - this.boxLeft - pageScrollLeft;
+          this.setPosi(posi);
+      });
     },
     setPosi(posi) {
       if (posi < 0 || posi > this.box.clientWidth) return;

+ 28 - 13
src/packages/slider/slider.vue

@@ -8,6 +8,7 @@
         @touchmove="onTouchMove"
         @touchend="onTouchEnd"
         @click="onTouchEnd"
+        @touchcancel="onTouchEnd"
         :style="{'left':posi+'px'}"
       >
         <span
@@ -20,6 +21,7 @@
   </div>
 </template>
 <script>
+import requestAniFrame from '../../utils/raf.js';
 export default {
   name: "nut-slider",
   props: {
@@ -59,7 +61,8 @@ export default {
       handle: null,
       posi: null,
       level: null,
-      ani: false
+      ani: false,
+      scheduledAnimationFrame:false
     };
   },
   computed: {
@@ -72,19 +75,27 @@ export default {
   },
   methods: {
     onTouchStart(event) {
-      event.preventDefault();
+      if (event.cancelable) {
+        event.preventDefault();
+      }
       this.ani = true;
     },
     onTouchMove(event) {
-      event.preventDefault();
-      event.stopPropagation();
-      event.cancelBubble = true;
-      const evt = event.touches[0];
-      const pageScrollLeft =
-        document.documentElement.scrollLeft || document.body.scrollLeft;
-      this.boxLeft = this.box.getBoundingClientRect().left;
-      const posi = evt.pageX - this.boxLeft - pageScrollLeft;
-      this.setPosi(posi);
+      if (event.cancelable) {
+        event.preventDefault();
+      }
+
+      if (this.scheduledAnimationFrame) return;
+
+      this.scheduledAnimationFrame = true;
+      requestAniFrame(() => {
+          this.scheduledAnimationFrame = false;
+          const evt = event.touches[0];
+          const pageScrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
+          this.boxLeft = this.box.getBoundingClientRect().left;
+          const posi = evt.pageX - this.boxLeft - pageScrollLeft;
+          this.setPosi(posi);
+      });
     },
     setVal(posi) {
       const trans = (posi / this.box.clientWidth) * this.total;
@@ -102,12 +113,16 @@ export default {
       this.setVal(posi);
     },
     onTouchEnd(event) {
-      event.preventDefault();
+      if (event.cancelable) {
+        event.preventDefault();
+      }
       this.posi = this.valToPosi();
       this.ani = false;
     },
     onClick(event) {
-      event.preventDefault();
+      if (event.cancelable) {
+        event.preventDefault();
+      }
       const pageScrollLeft =
         document.documentElement.scrollLeft || document.body.scrollLeft;
       this.boxLeft = this.box.getBoundingClientRect().left;

+ 12 - 0
src/utils/raf.js

@@ -0,0 +1,12 @@
+function requestAniFrame() {
+    return (
+        window.requestAnimationFrame ||
+        window.webkitRequestAnimationFrame ||
+        window.mozRequestAnimationFrame ||
+        function (callback) {
+            window.setTimeout(callback, 1000 / 60);
+        }
+    );
+}
+
+export default requestAniFrame();