From 13b96df98cab5682de707ac9c2565631cc82f3ac Mon Sep 17 00:00:00 2001 From: robiseb Date: Wed, 16 Feb 2022 15:15:22 +0100 Subject: [PATCH] Add scrollto parameters (#4) * Fix issue #3 * Some improvements * Readme updated --- package.json | 2 +- readme.md | 36 +++++++++++++++- src/index.js | 119 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 149 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index fb03e99..214dfd4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@wide/scroll", - "version": "2.1.0", + "version": "2.1.1", "description": "Observe scroll progression and provides helpers for parallax, locking and sticky effects.", "license": "MIT", "author": "Aymeric Assier (https://github.com/myeti)", diff --git a/readme.md b/readme.md index 7a9708b..8eb03cb 100644 --- a/readme.md +++ b/readme.md @@ -79,6 +79,41 @@ import { JUMP_CONFIG } from '@wide/scroll' JUMP_CONFIG.offset = -20 // top offset for all jump ``` +You can aslo define config locally by adding HTML attributes: +```html + +``` +```js +window.scrollToCallback = () => { + // Do some stuffs when scroll has been completed +} + +window.scrollToEasing = () => { + // My custom easing animation code +} +``` + +> Note: Those parameters will override default (global) parameters. + +### Parameters +| Name | Type | Description | Default value | +|---|---|---|---| +| `duration` | `number` | Pass the time the `scrollto()` takes, in milliseconds. | `800` | +| `offset` | `number` | Offset a `scrollto()`, only if to an element, by a number of pixels. | `-80` | +| `a11y` | `boolean` | If enabled, and scrolling to an element: add a tabindex to, and focus the element | `true` | +| `callback` | `function` | Pass a function that will be called after the `scrollto()` has been completed. | `null` | +| `easing` | `function` | Easing function used to transition the `scrollto()`. | `null` | + +More informations on [`Jump.js` documentation](https://github.com/callmecavs/jump.js#options). ## Locker @@ -138,7 +173,6 @@ const el = document.querySelector('.something') parallax(el, { speed: .4 }) ``` - ## Sticky Internally use [`stickybits`](https://www.npmjs.com/package/stickybits) library. diff --git a/src/index.js b/src/index.js index 1076fe4..6d36f3e 100644 --- a/src/index.js +++ b/src/index.js @@ -4,22 +4,59 @@ import jump from 'jump.js' import uos from 'uos' +/** + * Data attribute keyword + * @type {string} + */ +const dataKeyword = 'scrollto' + + +/** + * Data attribute option separator + * @type {string} + */ +const dataSeparator = '.' + + /** * Jump default config * @type {Object} + * + * @tutorial https://github.com/callmecavs/jump.js/blob/master/src/jump.js#L88 */ -export let JUMP_CONFIG = { +export const JUMP_CONFIG = { duration: 800, offset: -80, - a11y: true + a11y: true, + callback: null, // Global function + easing: null // Global function +} + + +/** + * Jump config variables type + * @type {Object} + * + * @tutorial https://github.com/callmecavs/jump.js/blob/master/src/jump.js#L88 + */ +export const JUMP_CONFIG_TYPE = { + duration: 'number', + offset: 'number', + a11y: 'boolean', + callback: 'function', + easing: 'function' } /** * Observe element [data-scrollto] in DOM to add effect */ -observe('[data-scrollto]', { - bind: el => el.addEventListener('click', e => to(e.dataset.scrollto)) +observe(`[data-${dataKeyword}]`, { + bind: el => el.addEventListener('click', () => { + if (el.dataset[dataKeyword]) { + scrollTo(document.querySelector(el.dataset.scrollto), getOptions(el.dataset)) + } + }) }) @@ -29,8 +66,78 @@ observe('[data-scrollto]', { * @param {Object} options */ export function scrollTo(target, options = {}) { - const opts = Object.assign({}, JUMP_CONFIG, options) - jump(target, opts) + if (target) { + const opts = Object.assign({}, JUMP_CONFIG, options) + jump(target, opts) + } +} + + +/** + * Get options from dataset + * @param {DOMStringMap} dataset + * @return {Object} Jump options + */ +function getOptions(dataset) { + const options = {} + + if (dataset && typeof dataset === 'object') { + for (const [dataName, dataValue] of Object.entries(dataset)) { + const optionName = getOptionName(dataName) + + if (optionName) { + const optionValue = getOptionValue(optionName, dataValue) + + if (optionValue !== null) { + options[optionName] = optionValue + } + } + } + } + + return options +} + + +/** + * Get option name from dataset name + * @param {string} dataName + * @return {string|null} Jump option name + */ +function getOptionName(dataName) { + const dataKeywordSeparator = dataKeyword + dataSeparator + + // If an option is setted... + if (dataName.startsWith(dataKeywordSeparator)) { + const dataOptionName = dataName.slice(dataKeywordSeparator.length) + + // ...and exists in jump.js, add it + return Object.hasOwn(JUMP_CONFIG, dataOptionName) ? dataOptionName : '' + } + + return null +} + + +/** + * Get option value from dataset string value + * @param {string} optionName + * @param {string} optionValue + * @return {any} Value formatted + */ +function getOptionValue(optionName, optionValue) { + if (!optionName) return null + + switch (JUMP_CONFIG_TYPE[optionName]) { + case 'boolean': + return optionValue === 'true' + case 'function': + return window[optionValue] || null + case 'number': + return optionValue * 1 + default: + return optionValue + } }