From e598b04a2890fdd8d09e8cb167984a6fae6b5fb9 Mon Sep 17 00:00:00 2001 From: Vincent Loy Date: Mon, 22 May 2017 13:00:07 +0200 Subject: [PATCH 1/2] Propagate events to parent node when not scrolled - Fix issue #7 --- src/js/components/vue-scrollbar.vue | 47 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/js/components/vue-scrollbar.vue b/src/js/components/vue-scrollbar.vue index d311052..5f1dedd 100644 --- a/src/js/components/vue-scrollbar.vue +++ b/src/js/components/vue-scrollbar.vue @@ -81,16 +81,24 @@ scrollWrapperWidth: null, vMovement: 0, hMovement: 0, + cachedvMovement: 0, dragging: false, start: { y: 0, x: 0} } }, - methods: { + computed: { + /** + * If vMovement and the cached one are the same, then parent scrolling is allowed. + * @returns {boolean} + */ + allowBodyScrollVertical() { + return this.vMovement === this.cachedvMovement; + } + }, + methods: { scroll(e){ - e.preventDefault() - // Make sure the content height is not changed this.calculateSize(() => { // Set the wheel step @@ -119,36 +127,41 @@ if(shifted && canScrollX) this.normalizeHorizontal(nextX) }) + // prevent Default only if scrolled content is not at the top/bottom + if (!this.allowBodyScrollVertical) { + e.preventDefault() + } + }, // DRAG EVENT JUST FOR TOUCH DEVICE~ startDrag(e){ - e.preventDefault() - e.stopPropagation() - - e = e.changedTouches ? e.changedTouches[0] : e + let evt = e.changedTouches ? e.changedTouches[0] : e // Make sure the content height is not changed this.calculateSize(() => { // Prepare to drag this.dragging = true, - this.start = { y: e.pageY, x: e.pageX } + this.start = { y: evt.pageY, x: evt.pageX } }) + // It's important to make this after size calculation + if (!this.allowBodyScrollVertical) { + e.preventDefault() + e.stopPropagation() + } }, onDrag(e){ if(this.dragging){ - - e.preventDefault() - e = e.changedTouches ? e.changedTouches[0] : e + let evt = e.changedTouches ? e.changedTouches[0] : e // Invers the Movement - let yMovement = this.start.y - e.clientY - let xMovement = this.start.x - e.clientX + let yMovement = this.start.y - evt.clientY + let xMovement = this.start.x - evt.clientX // Update the last e.client - this.start = { y: e.clientY, x: e.clientX } + this.start = { y: evt.clientY, x: evt.clientX } // The next Vertical Value will be let nextY = this.top + yMovement @@ -157,6 +170,9 @@ this.normalizeVertical(nextY) this.normalizeHorizontal(nextX) + if (!this.allowBodyScrollVertical) { + e.preventDefault() + } } }, @@ -184,8 +200,9 @@ // Max Scroll Up else if(next < 0) next = 0 - // Update the Vertical Value + // Cache previous Vertical movement value & Update the Vertical Value this.top = next, + this.cachedvMovement = this.vMovement this.vMovement = next / elementSize.scrollAreaHeight * 100 }, From 3929efb980eb539b933635d85350b085a6df732c Mon Sep 17 00:00:00 2001 From: Vincent Loy Date: Mon, 22 May 2017 13:02:42 +0200 Subject: [PATCH 2/2] Build changes - Fix issue #7 --- build/build.js | 4 ++-- dist/vue2-scrollbar.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/build.js b/build/build.js index f44807e..5201b3a 100644 --- a/build/build.js +++ b/build/build.js @@ -1,3 +1,3 @@ -!function(n){function e(r){if(t[r])return t[r].exports;var o=t[r]={exports:{},id:r,loaded:!1};return n[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var t={};return e.m=n,e.c=t,e.p="/build/",e(0)}([function(module,exports,__webpack_require__){eval("'use strict';\n\nvar _vue = __webpack_require__(19);\n\nvar _vue2 = _interopRequireDefault(_vue);\n\nvar _app = __webpack_require__(11);\n\nvar _app2 = _interopRequireDefault(_app);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n_vue2.default.config.debug = true;\n_vue2.default.config.devtools = true;\n\nnew _vue2.default(_vue2.default.util.extend(_app2.default)).$mount('app');\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/js/main.js\n// module id = 0\n// module chunks = 0\n//# sourceURL=webpack:///./src/js/main.js?")},function(module,exports){eval('/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push("@media " + item[2] + "{" + item[1] + "}");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join("");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === "string")\r\n\t\t\tmodules = [[null, modules, ""]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === "number")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = "(" + item[2] + ") and (" + mediaQuery + ")";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 1\n// module chunks = 0\n//# sourceURL=webpack:///./~/css-loader/lib/css-base.js?')},function(module,exports,__webpack_require__){eval('/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\nvar stylesInDom = {},\r\n\tmemoize = function(fn) {\r\n\t\tvar memo;\r\n\t\treturn function () {\r\n\t\t\tif (typeof memo === "undefined") memo = fn.apply(this, arguments);\r\n\t\t\treturn memo;\r\n\t\t};\r\n\t},\r\n\tisOldIE = memoize(function() {\r\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\r\n\t}),\r\n\tgetHeadElement = memoize(function () {\r\n\t\treturn document.head || document.getElementsByTagName("head")[0];\r\n\t}),\r\n\tsingletonElement = null,\r\n\tsingletonCounter = 0,\r\n\tstyleElementsInsertedAtTop = [];\r\n\r\nmodule.exports = function(list, options) {\r\n\tif(false) {\r\n\t\tif(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");\r\n\t}\r\n\r\n\toptions = options || {};\r\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of