From f082ff12ace87a20298c29b28f779f6a79328188 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Mon, 27 Feb 2017 19:58:42 +0100 Subject: [PATCH] Adding new features --- src/js/modules/webslides.js | 13 +++++++++++-- src/js/plugins/click-nav.js | 38 +++++++++++++++++++++++++++++++++++++ src/js/plugins/plugins.js | 2 ++ src/js/plugins/scroll.js | 37 ++++++++++++++++++++++++++++++------ 4 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/js/plugins/click-nav.js diff --git a/src/js/modules/webslides.js b/src/js/modules/webslides.js index 988e6f2..eb05041 100644 --- a/src/js/modules/webslides.js +++ b/src/js/modules/webslides.js @@ -9,6 +9,7 @@ const CLASSES = { // Default plugins const PLUGINS = { + 'clickNav': Plugins.ClickNav, 'grid': Plugins.Grid, 'hash': Plugins.Hash, 'keyboard': Plugins.Keyboard, @@ -21,10 +22,12 @@ export default class WebSlides { /** * Options for WebSlides * @param {number|boolean} autoslide Is false by default. If a number is - * provided, it will autoslide every given milliseconds. + * @param {boolean} changeOnClick Is false by default. If true, it will allow + * clicking on any place to change the slide. */ constructor({ - autoslide = false + autoslide = false, + changeOnClick = false } = {}) { /** * WebSlide element. @@ -82,6 +85,12 @@ export default class WebSlides { * @private */ this.autoslide_ = autoslide; + /** + * Whether navigation should initiate on click + * @type {boolean} + * @private + */ + this.changeOnClick_ = changeOnClick; if (!this.el) { throw new Error('Couldn\'t find the webslides container!'); diff --git a/src/js/plugins/click-nav.js b/src/js/plugins/click-nav.js new file mode 100644 index 0000000..e3ec506 --- /dev/null +++ b/src/js/plugins/click-nav.js @@ -0,0 +1,38 @@ +const CLICKABLE_ELS = [ + 'INPUT', + 'SELECT', + 'BUTTON', + 'A', + 'TEXTAREA' +]; + +export default class ClickNav { + /** + * ClickNav plugin that allows to click on the page to get to the next slide. + * @param {WebSlides} wsInstance The WebSlides instance + */ + constructor(wsInstance) { + /** + * @type {WebSlides} + * @private + */ + this.ws_ = wsInstance; + + if (wsInstance.changeOnClick) { + this.ws_.el.addEventListener('click', this.onClick_.bind(this)); + } + } + + /** + * Reacts to the click event. It will go to the next slide unless the element + * has a data-prevent-nav attribute or is on the list of CLICKABLE_ELS. + * @param {MouseEvent} event The click event. + * @private + */ + onClick_(event) { + if (CLICKABLE_ELS.indexOf(event.target.tagName) < 0 && + typeof event.target.dataset.preventNav === 'undefined') { + this.ws_.goNext(); + } + } +} diff --git a/src/js/plugins/plugins.js b/src/js/plugins/plugins.js index 4e7d6e2..6b35620 100644 --- a/src/js/plugins/plugins.js +++ b/src/js/plugins/plugins.js @@ -1,3 +1,4 @@ +import ClickNav from './click-nav'; import Grid from './grid'; import Hash from './hash'; import Keyboard from './keyboard'; @@ -6,6 +7,7 @@ import Scroll from './scroll'; import Touch from './touch'; export default { + ClickNav, Grid, Hash, Keyboard, diff --git a/src/js/plugins/scroll.js b/src/js/plugins/scroll.js index 16b986e..611ab90 100644 --- a/src/js/plugins/scroll.js +++ b/src/js/plugins/scroll.js @@ -16,13 +16,29 @@ export default class Scroll { this.scrollContainer_ = wsInstance.el; this.isGoingUp_ = false; + this.isGoingLeft_ = false; + this.timeout_ = null; - if (this.ws_.isVertical && !MobileDetector.isAny()) { + if (!MobileDetector.isAny()) { this.scrollContainer_.addEventListener( 'wheel', this.onMouseWheel_.bind(this)); + + if (!wsInstance.isVertical) { + wsInstance.el.addEventListener( + 'ws:slide-change', this.onSlideChange_.bind(this)); + } } } + /** + * When the slides change, set an inner timeout to avoid prematurely + * changing to the next slide again. + * @private + */ + onSlideChange_() { + this.timeout_ = setTimeout(() => { this.timeout_ = null; }, 400); + } + /** * Reacts to the wheel event. Detects whether is going up or down and decides * if it needs to move the slide based on the amount of delta. @@ -30,16 +46,25 @@ export default class Scroll { * @private */ onMouseWheel_(event) { - if (this.ws_.isMoving) { + if (this.ws_.isMoving || this.timeout_) { event.preventDefault(); return; } - const { deltaY: wheelDelta } = event; - this.isGoingUp_ = wheelDelta < 0; + const { deltaY: wheelDeltaY, deltaX: wheelDeltaX } = event; + this.isGoingUp_ = wheelDeltaY < 0; + this.isGoingLeft_ = wheelDeltaX < 0; - if (Math.abs(wheelDelta) >= MIN_WHEEL_DELTA) { - if (this.isGoingUp_) { + if (!this.ws_.isVertical) { + // If we're mainly moving horizontally, prevent default + if (Math.abs(wheelDeltaX) > Math.abs(wheelDeltaY)) { + event.preventDefault(); + } + } + + if (Math.abs(wheelDeltaY) >= MIN_WHEEL_DELTA || + Math.abs(wheelDeltaX) >= MIN_WHEEL_DELTA) { + if (this.isGoingUp_ || this.isGoingLeft_) { this.ws_.goPrev(); } else { this.ws_.goNext();