UNPKG

@pharrellwang/react-router-hash-link

Version:

Hash link scroll functionality for React Router v4

93 lines (76 loc) 2.88 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.HashLink = HashLink; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactRouterDom = require('react-router-dom'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var hashFragment = ''; var observer = null; var asyncTimerId = null; function reset() { hashFragment = ''; if (observer !== null) observer.disconnect(); if (asyncTimerId !== null) { window.clearTimeout(asyncTimerId); asyncTimerId = null; } } function getElAndScroll() { var element = document.getElementById(hashFragment); if (element !== null) { element.scrollIntoView(); var scrolledY = window.scrollY; if (scrolledY) { // window.scroll(0, scrolledY - '[your header height in pixels]'); //E.g., window.scroll(0, scrolledY - 64); } reset(); return true; } return false; } function hashLinkScroll() { // Push onto callback queue so it runs after the DOM is updated window.setTimeout(function () { if (getElAndScroll() === false) { if (observer === null) { observer = new MutationObserver(getElAndScroll); } observer.observe(document, { attributes: true, childList: true, subtree: true }); // if the element doesn't show up in 10 seconds, stop checking asyncTimerId = window.setTimeout(function () { reset(); }, 10000); } }, 0); } function HashLink(props) { function handleClick(e) { reset(); if (props.onClick) props.onClick(e); if (typeof props.to === 'string') { hashFragment = props.to.split('#').slice(1).join('#'); } else if (_typeof(props.to) === 'object' && typeof props.to.hash === 'string') { hashFragment = props.to.hash.replace('#', ''); } if (hashFragment !== '') hashLinkScroll(); } return _react2.default.createElement( _reactRouterDom.Link, _extends({}, props, { onClick: handleClick }), props.children ); } HashLink.propTypes = { onClick: _propTypes2.default.func, children: _propTypes2.default.node, to: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]) };