From 4caf4666072cb5e18c06a46ca3c802b6a245a539 Mon Sep 17 00:00:00 2001 From: Mark de Cates Date: Thu, 19 Oct 2017 13:47:21 +0100 Subject: [PATCH 1/4] Add delay option --- src/utils/helpers.js | 12 +++++++++--- src/vue-scroll-behavior.js | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/utils/helpers.js b/src/utils/helpers.js index aeb22a0..f7c0d60 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -12,6 +12,10 @@ export function setOption (options) { if (typeof options.ignore !== 'undefined' && Array.isArray(options.ignore)) { vueScrollBehavior._ignore = options.ignore } + + if (typeof options.delay === 'number') { + vueScrollBehavior._delay = options.delay + } } /** @@ -28,9 +32,11 @@ export function getScrollPosition () { * Setting Scroll Position */ export function setScrollPosition (Vue, position = {x: 0, y: 0}) { - Vue.nextTick(() => { - window.scrollTo(position.x, position.y) - }) + setTimeout(() => { + Vue.nextTick(() => { + window.scrollTo(position.x, position.y) + }) + }, vueScrollBehavior._delay); } /** diff --git a/src/vue-scroll-behavior.js b/src/vue-scroll-behavior.js index f4da636..d59ba39 100644 --- a/src/vue-scroll-behavior.js +++ b/src/vue-scroll-behavior.js @@ -9,7 +9,8 @@ import { setOption, isIgnoreRoute, getScrollPosition, setScrollPosition, const vueScrollBehavior = { _maxLength: 50, - _ignore: [] + _ignore: [], + _delay: 0 } /** From e854fdc5b033247b46514ed38af86d2f0b7a69ca Mon Sep 17 00:00:00 2001 From: Mark de Cates Date: Thu, 19 Oct 2017 13:55:13 +0100 Subject: [PATCH 2/4] Update README for delay option --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c8c174..981267e 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ When using client-side routing, we may want to scroll to top when navigating to **Of course, If you have some special scenes, we also provide some options, and you can manually use them to save or restore the scroll position** +**If you use transitions on all of your route changes, use the _delay_ option to delay the scroll until the appropriate point (e.g. the middle of the changeover).** ## Features * **Simplicity** - only need to call `Vue.vueScrollBehavior(router)` @@ -87,7 +88,8 @@ import vueScrollBehavior from 'vue-scroll-behavior' Vue.use(vueScrollBehavior, { router: router, // The router instance maxLength: 100, // Saved history List max length - ignore: [/\/boo/, /\/zoo/] // ignore some routes, they will directly scroll to the top + ignore: [/\/boo/, /\/zoo/], // ignore some routes, they will directly scroll to the top + delay: 0 // Delay by a number of milliseconds }) ``` @@ -112,6 +114,7 @@ Prop | Data Type | Default | Description `router` | Object | | The router instance: `const router = new VueRouter({})` `ignore` | Array | `[ ]` | **RegExp** list to ignore some routes, they will directly scroll to the top `maxLength` | Number | `50` | Saved history List max length +`delay` | Number | `0` | Delay scroll by a number of milliseconds ## ChangeLog From 9085e495beaba8c30cab0d7755b5c109d7dbaab5 Mon Sep 17 00:00:00 2001 From: Mark de Cates Date: Thu, 19 Oct 2017 14:00:47 +0100 Subject: [PATCH 3/4] Updated dist js with delay option --- dist/vue-scroll-behavior.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/vue-scroll-behavior.js b/dist/vue-scroll-behavior.js index 6767f5c..7d3f102 100644 --- a/dist/vue-scroll-behavior.js +++ b/dist/vue-scroll-behavior.js @@ -3,4 +3,4 @@ * (c) 2017 jeneser * @license MIT */ -!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.vueScrollBehavior=n()}(this,function(){"use strict";function e(e){void 0!==e.maxLength&&"number"==typeof e.maxLength&&(u._maxLength=e.maxLength),void 0!==e.ignore&&Array.isArray(e.ignore)&&(u._ignore=e.ignore)}function n(){return{x:window.pageXOffset,y:window.pageYOffset}}function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{x:0,y:0};e.nextTick(function(){window.scrollTo(n.x,n.y)})}function o(e){e.splice(0,parseInt(e.length/2))}function r(e){u._ignore.some(function(n){return e.fullPath.match(n)})}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u=(function(){function e(e){this.value=e}function n(n){function t(e,n){return new Promise(function(t,r){var f={key:e,arg:n,resolve:t,reject:r,next:null};u?u=u.next=f:(i=u=f,o(e,n))})}function o(t,i){try{var u=n[t](i),f=u.value;f instanceof e?Promise.resolve(f.value).then(function(e){o("next",e)},function(e){o("throw",e)}):r(u.done?"return":"normal",u.value)}catch(e){r("throw",e)}}function r(e,n){switch(e){case"return":i.resolve({value:n,done:!0});break;case"throw":i.reject(n);break;default:i.resolve({value:n,done:!1})}i=i.next,i?o(i.key,i.arg):u=null}var i,u;this._invoke=t,"function"!=typeof n.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(n.prototype[Symbol.asyncIterator]=function(){return this}),n.prototype.next=function(e){return this._invoke("next",e)},n.prototype.throw=function(e){return this._invoke("throw",e)},n.prototype.return=function(e){return this._invoke("return",e)}}(),{_maxLength:50,_ignore:[]});return u.install=function(f,c){e(c),f.vsbHistoryList=[],f.vueScrollBehavior=function(e){var c=this;"object"===(void 0===e?"undefined":i(e))&&"function"==typeof e.beforeEach?(e.beforeEach(function(e,t,i){if(r(t))i();else{var f=c.vsbHistoryList,a=n(),l=f.findIndex(function(e){return e.path===t.fullPath});f.length>=u._maxLength&&o(f),-1!==l?f[l].position=a:f.push({path:t.fullPath,position:a}),i()}}),e.afterEach(function(e){if(r(e))t(f);else{var n=c.vsbHistoryList.find(function(n){return n.path===e.fullPath});void 0!==n?t(f,n.position):t(f)}})):console.warn("Vue-scroll-behavior dependent on vue-router! Please create the router instance.")},f.vueScrollBehavior(c.router)},"undefined"!=typeof window&&window.Vue&&window.Vue.use(u),u}); +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.vueScrollBehavior=n()}(this,function(){"use strict";function e(e){void 0!==e.maxLength&&"number"==typeof e.maxLength&&(u._maxLength=e.maxLength),void 0!==e.ignore&&Array.isArray(e.ignore)&&(u._ignore=e.ignore),"number"==typeof e.delay&&(u._delay=e.delay)}function n(){return{x:window.pageXOffset,y:window.pageYOffset}}function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{x:0,y:0};setTimeout(function(){e.nextTick(function(){window.scrollTo(n.x,n.y)})},u._delay)}function o(e){e.splice(0,parseInt(e.length/2))}function r(e){u._ignore.some(function(n){return e.fullPath.match(n)})}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u=(function(){function e(e){this.value=e}function n(n){function t(e,n){return new Promise(function(t,r){var f={key:e,arg:n,resolve:t,reject:r,next:null};u?u=u.next=f:(i=u=f,o(e,n))})}function o(t,i){try{var u=n[t](i),f=u.value;f instanceof e?Promise.resolve(f.value).then(function(e){o("next",e)},function(e){o("throw",e)}):r(u.done?"return":"normal",u.value)}catch(e){r("throw",e)}}function r(e,n){switch(e){case"return":i.resolve({value:n,done:!0});break;case"throw":i.reject(n);break;default:i.resolve({value:n,done:!1})}i=i.next,i?o(i.key,i.arg):u=null}var i,u;this._invoke=t,"function"!=typeof n.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(n.prototype[Symbol.asyncIterator]=function(){return this}),n.prototype.next=function(e){return this._invoke("next",e)},n.prototype.throw=function(e){return this._invoke("throw",e)},n.prototype.return=function(e){return this._invoke("return",e)}}(),{_maxLength:50,_ignore:[],_delay:0});return u.install=function(f,a){e(a),f.vsbHistoryList=[],f.vueScrollBehavior=function(e){var a=this;"object"===(void 0===e?"undefined":i(e))&&"function"==typeof e.beforeEach?(e.beforeEach(function(e,t,i){if(r(t))i();else{var f=a.vsbHistoryList,c=n(),l=f.findIndex(function(e){return e.path===t.fullPath});f.length>=u._maxLength&&o(f),-1!==l?f[l].position=c:f.push({path:t.fullPath,position:c}),i()}}),e.afterEach(function(e){if(r(e))t(f);else{var n=a.vsbHistoryList.find(function(n){return n.path===e.fullPath});void 0!==n?t(f,n.position):t(f)}})):console.warn("Vue-scroll-behavior dependent on vue-router! Please create the router instance.")},f.vueScrollBehavior(a.router)},"undefined"!=typeof window&&window.Vue&&window.Vue.use(u),u}); From 780367954aff0ddeedd0269b9f3b9da0822063ab Mon Sep 17 00:00:00 2001 From: Mark de Cates Date: Fri, 27 Oct 2017 10:35:55 +0100 Subject: [PATCH 4/4] Ensure existing behaviour without delay --- dist/vue-scroll-behavior.js | 2 +- src/utils/helpers.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dist/vue-scroll-behavior.js b/dist/vue-scroll-behavior.js index 7d3f102..5469418 100644 --- a/dist/vue-scroll-behavior.js +++ b/dist/vue-scroll-behavior.js @@ -3,4 +3,4 @@ * (c) 2017 jeneser * @license MIT */ -!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.vueScrollBehavior=n()}(this,function(){"use strict";function e(e){void 0!==e.maxLength&&"number"==typeof e.maxLength&&(u._maxLength=e.maxLength),void 0!==e.ignore&&Array.isArray(e.ignore)&&(u._ignore=e.ignore),"number"==typeof e.delay&&(u._delay=e.delay)}function n(){return{x:window.pageXOffset,y:window.pageYOffset}}function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{x:0,y:0};setTimeout(function(){e.nextTick(function(){window.scrollTo(n.x,n.y)})},u._delay)}function o(e){e.splice(0,parseInt(e.length/2))}function r(e){u._ignore.some(function(n){return e.fullPath.match(n)})}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u=(function(){function e(e){this.value=e}function n(n){function t(e,n){return new Promise(function(t,r){var f={key:e,arg:n,resolve:t,reject:r,next:null};u?u=u.next=f:(i=u=f,o(e,n))})}function o(t,i){try{var u=n[t](i),f=u.value;f instanceof e?Promise.resolve(f.value).then(function(e){o("next",e)},function(e){o("throw",e)}):r(u.done?"return":"normal",u.value)}catch(e){r("throw",e)}}function r(e,n){switch(e){case"return":i.resolve({value:n,done:!0});break;case"throw":i.reject(n);break;default:i.resolve({value:n,done:!1})}i=i.next,i?o(i.key,i.arg):u=null}var i,u;this._invoke=t,"function"!=typeof n.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(n.prototype[Symbol.asyncIterator]=function(){return this}),n.prototype.next=function(e){return this._invoke("next",e)},n.prototype.throw=function(e){return this._invoke("throw",e)},n.prototype.return=function(e){return this._invoke("return",e)}}(),{_maxLength:50,_ignore:[],_delay:0});return u.install=function(f,a){e(a),f.vsbHistoryList=[],f.vueScrollBehavior=function(e){var a=this;"object"===(void 0===e?"undefined":i(e))&&"function"==typeof e.beforeEach?(e.beforeEach(function(e,t,i){if(r(t))i();else{var f=a.vsbHistoryList,c=n(),l=f.findIndex(function(e){return e.path===t.fullPath});f.length>=u._maxLength&&o(f),-1!==l?f[l].position=c:f.push({path:t.fullPath,position:c}),i()}}),e.afterEach(function(e){if(r(e))t(f);else{var n=a.vsbHistoryList.find(function(n){return n.path===e.fullPath});void 0!==n?t(f,n.position):t(f)}})):console.warn("Vue-scroll-behavior dependent on vue-router! Please create the router instance.")},f.vueScrollBehavior(a.router)},"undefined"!=typeof window&&window.Vue&&window.Vue.use(u),u}); +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.vueScrollBehavior=n()}(this,function(){"use strict";function e(e){void 0!==e.maxLength&&"number"==typeof e.maxLength&&(u._maxLength=e.maxLength),void 0!==e.ignore&&Array.isArray(e.ignore)&&(u._ignore=e.ignore),"number"==typeof e.delay&&(u._delay=e.delay)}function n(){return{x:window.pageXOffset,y:window.pageYOffset}}function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{x:0,y:0};u._delay>0?setTimeout(function(){e.nextTick(function(){window.scrollTo(n.x,n.y)})},u._delay):e.nextTick(function(){window.scrollTo(n.x,n.y)})}function o(e){e.splice(0,parseInt(e.length/2))}function r(e){u._ignore.some(function(n){return e.fullPath.match(n)})}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u=(function(){function e(e){this.value=e}function n(n){function t(e,n){return new Promise(function(t,r){var f={key:e,arg:n,resolve:t,reject:r,next:null};u?u=u.next=f:(i=u=f,o(e,n))})}function o(t,i){try{var u=n[t](i),f=u.value;f instanceof e?Promise.resolve(f.value).then(function(e){o("next",e)},function(e){o("throw",e)}):r(u.done?"return":"normal",u.value)}catch(e){r("throw",e)}}function r(e,n){switch(e){case"return":i.resolve({value:n,done:!0});break;case"throw":i.reject(n);break;default:i.resolve({value:n,done:!1})}i=i.next,i?o(i.key,i.arg):u=null}var i,u;this._invoke=t,"function"!=typeof n.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(n.prototype[Symbol.asyncIterator]=function(){return this}),n.prototype.next=function(e){return this._invoke("next",e)},n.prototype.throw=function(e){return this._invoke("throw",e)},n.prototype.return=function(e){return this._invoke("return",e)}}(),{_maxLength:50,_ignore:[],_delay:0});return u.install=function(f,c){e(c),f.vsbHistoryList=[],f.vueScrollBehavior=function(e){var c=this;"object"===(void 0===e?"undefined":i(e))&&"function"==typeof e.beforeEach?(e.beforeEach(function(e,t,i){if(r(t))i();else{var f=c.vsbHistoryList,a=n(),l=f.findIndex(function(e){return e.path===t.fullPath});f.length>=u._maxLength&&o(f),-1!==l?f[l].position=a:f.push({path:t.fullPath,position:a}),i()}}),e.afterEach(function(e){if(r(e))t(f);else{var n=c.vsbHistoryList.find(function(n){return n.path===e.fullPath});void 0!==n?t(f,n.position):t(f)}})):console.warn("Vue-scroll-behavior dependent on vue-router! Please create the router instance.")},f.vueScrollBehavior(c.router)},"undefined"!=typeof window&&window.Vue&&window.Vue.use(u),u}); diff --git a/src/utils/helpers.js b/src/utils/helpers.js index f7c0d60..86afac8 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -32,11 +32,17 @@ export function getScrollPosition () { * Setting Scroll Position */ export function setScrollPosition (Vue, position = {x: 0, y: 0}) { - setTimeout(() => { + if (vueScrollBehavior._delay > 0) { + setTimeout(() => { + Vue.nextTick(() => { + window.scrollTo(position.x, position.y) + }) + }, vueScrollBehavior._delay); + } else { Vue.nextTick(() => { window.scrollTo(position.x, position.y) }) - }, vueScrollBehavior._delay); + } } /**