ソースを参照

Table: forward fixed column's mousewheel event to entire table (#9323)

FuryBean 7 年 前
コミット
bbe6e62ee1
5 ファイル変更57 行追加29 行削除
  1. 1 0
      package.json
  2. 34 21
      packages/table/src/table.vue
  3. 0 8
      packages/table/src/util.js
  4. 18 0
      src/directives/mousewheel.js
  5. 4 0
      yarn.lock

+ 1 - 0
package.json

@@ -54,6 +54,7 @@
     "async-validator": "~1.8.1",
     "babel-helper-vue-jsx-merge-props": "^2.0.0",
     "deepmerge": "^1.2.0",
+    "normalize-wheel": "^1.0.1",
     "throttle-debounce": "^1.0.1"
   },
   "peerDependencies": {

+ 34 - 21
packages/table/src/table.vue

@@ -12,7 +12,7 @@
     }, tableSize ? `el-table--${ tableSize }` : '']"
     @mouseleave="handleMouseLeave($event)">
     <div class="hidden-columns" ref="hiddenColumns"><slot></slot></div>
-    <div class="el-table__header-wrapper" ref="headerWrapper" v-if="showHeader">
+    <div class="el-table__header-wrapper" ref="headerWrapper" v-if="showHeader" v-mousewheel="handleHeaderFooterMousewheel">
       <table-header
         ref="tableHeader"
         :store="store"
@@ -44,7 +44,7 @@
         <slot name="append"></slot>
       </div>
     </div>
-    <div class="el-table__footer-wrapper" ref="footerWrapper" v-if="showSummary" v-show="data && data.length > 0">
+    <div class="el-table__footer-wrapper" ref="footerWrapper" v-if="showSummary" v-show="data && data.length > 0" v-mousewheel="handleHeaderFooterMousewheel">
       <table-footer
         :store="store"
         :layout="layout"
@@ -57,6 +57,7 @@
     </div>
     <div class="el-table__fixed" ref="fixedWrapper"
       v-if="fixedColumns.length > 0"
+      v-mousewheel="handleFixedMousewheel"
       :style="[
         { width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' },
         fixedHeight
@@ -102,6 +103,7 @@
     </div>
     <div class="el-table__fixed-right" ref="rightFixedWrapper"
       v-if="rightFixedColumns.length > 0"
+      v-mousewheel="handleFixedMousewheel"
       :style="[
         { width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' },
         { right: layout.scrollY ? (border ? layout.gutterWidth : (layout.gutterWidth || 0)) + 'px' : '' },
@@ -155,6 +157,7 @@
   import throttle from 'throttle-debounce/throttle';
   import debounce from 'throttle-debounce/debounce';
   import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
+  import Mousewheel from 'element-ui/src/directives/mousewheel';
   import Locale from 'element-ui/src/mixins/locale';
   import Migrating from 'element-ui/src/mixins/migrating';
   import TableStore from './table-store';
@@ -162,7 +165,6 @@
   import TableBody from './table-body';
   import TableHeader from './table-header';
   import TableFooter from './table-footer';
-  import { mousewheel } from './util';
 
   let tableIdSeed = 1;
 
@@ -171,6 +173,10 @@
 
     mixins: [Locale, Migrating],
 
+    directives: {
+      Mousewheel
+    },
+
     props: {
       data: {
         type: Array,
@@ -294,10 +300,35 @@
         this.layout.updateScrollY();
       },
 
+      handleFixedMousewheel(event, data) {
+        const bodyWrapper = this.bodyWrapper;
+        if (Math.abs(data.spinY) > 0) {
+          const currentScrollTop = bodyWrapper.scrollTop;
+          if (data.pixelY < 0 && currentScrollTop !== 0) {
+            event.preventDefault();
+          }
+          if (data.pixelY > 0 && bodyWrapper.scrollHeight - bodyWrapper.clientHeight > currentScrollTop) {
+            event.preventDefault();
+          }
+          bodyWrapper.scrollTop += Math.ceil(data.pixelY / 5);
+        } else {
+          bodyWrapper.scrollLeft += Math.ceil(data.pixelX / 5);
+        }
+      },
+
+      handleHeaderFooterMousewheel(event, data) {
+        const { pixelX, pixelY } = data;
+        if (Math.abs(pixelX) >= Math.abs(pixelY)) {
+          event.preventDefault();
+          this.bodyWrapper.scrollLeft += data.pixelX / 5;
+        }
+      },
+
       bindEvents() {
         const { headerWrapper, footerWrapper } = this.$refs;
         const refs = this.$refs;
         let self = this;
+
         this.bodyWrapper.addEventListener('scroll', function() {
           if (headerWrapper) headerWrapper.scrollLeft = this.scrollLeft;
           if (footerWrapper) footerWrapper.scrollLeft = this.scrollLeft;
@@ -314,24 +345,6 @@
           }
         });
 
-        const scrollBodyWrapper = event => {
-          const { deltaX, deltaY } = event;
-
-          if (Math.abs(deltaX) < Math.abs(deltaY)) return;
-
-          if (deltaX > 0) {
-            this.bodyWrapper.scrollLeft += 10;
-          } else if (deltaX < 0) {
-            this.bodyWrapper.scrollLeft -= 10;
-          }
-        };
-        if (headerWrapper) {
-          mousewheel(headerWrapper, throttle(16, scrollBodyWrapper));
-        }
-        if (footerWrapper) {
-          mousewheel(footerWrapper, throttle(16, scrollBodyWrapper));
-        }
-
         if (this.fit) {
           this.windowResizeListener = throttle(50, () => {
             if (this.$ready) this.doLayout();

+ 0 - 8
packages/table/src/util.js

@@ -92,14 +92,6 @@ export const getColumnByCell = function(table, cell) {
   return null;
 };
 
-const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
-
-export const mousewheel = function(element, callback) {
-  if (element && element.addEventListener) {
-    element.addEventListener(isFirefox ? 'DOMMouseScroll' : 'mousewheel', callback, { passive: true });
-  }
-};
-
 export const getRowIdentity = (row, rowKey) => {
   if (!row) throw new Error('row is required when get row identity');
   if (typeof rowKey === 'string') {

+ 18 - 0
src/directives/mousewheel.js

@@ -0,0 +1,18 @@
+import normalizeWheel from 'normalize-wheel';
+
+const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
+
+const mousewheel = function(element, callback) {
+  if (element && element.addEventListener) {
+    element.addEventListener(isFirefox ? 'DOMMouseScroll' : 'mousewheel', function(event) {
+      const normalized = normalizeWheel(event);
+      callback && callback.apply(this, [event, normalized]);
+    });
+  }
+};
+
+export default {
+  bind(el, binding) {
+    mousewheel(el, binding.value);
+  }
+};

+ 4 - 0
yarn.lock

@@ -5500,6 +5500,10 @@ normalize-url@^1.4.0:
     query-string "^4.1.0"
     sort-keys "^1.0.0"
 
+normalize-wheel@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45"
+
 npm-run-path@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"