Skip to content

Commit c9a34e0

Browse files
committed
Merge branch 'async-el-loading-scroll'
2 parents 719229f + cb73ded commit c9a34e0

File tree

1 file changed

+44
-7
lines changed

1 file changed

+44
-7
lines changed

src/index.js

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,61 @@
11
import React, { PropTypes } from 'react';
22
import { Link } from 'react-router-dom';
33

4-
function hashLinkScroll(hashFragment) {
4+
let hashFragment = '';
5+
let observer = null;
6+
let asyncTimer = null;
7+
8+
function reset() {
9+
hashFragment = '';
10+
if (observer !== null) observer.disconnect();
11+
if (asyncTimer !== null) {
12+
window.clearTimeout(asyncTimer);
13+
asyncTimer = null;
14+
}
15+
}
16+
17+
function getElAndScroll() {
18+
const element = document.getElementById(hashFragment);
19+
if (element !== null) {
20+
element.scrollIntoView();
21+
reset();
22+
return true;
23+
}
24+
return false;
25+
}
26+
27+
function setupMutationObserver() {
28+
observer = new MutationObserver(getElAndScroll);
29+
}
30+
31+
function hashLinkScroll() {
532
// Push onto callback queue so it runs after the DOM is updated
633
setTimeout(() => {
7-
const element = document.getElementById(hashFragment);
8-
if (element !== null) element.scrollIntoView();
34+
if (getElAndScroll() === false) {
35+
if (observer === null) setupMutationObserver();
36+
observer.observe(document, { attributes: true, childList: true, subtree: true });
37+
if (asyncTimer !== null) window.clearTimeout(asyncTimer);
38+
// if the element doesn't show up in 10 seconds, stop checking
39+
asyncTimer = window.setTimeout(() => {
40+
reset();
41+
}, 10000);
42+
}
943
}, 0);
1044
}
1145

1246
export function HashLink(props) {
1347
function handleClick(e) {
1448
if (props.onClick) props.onClick(e);
15-
let hashFragment = '';
49+
let hash = '';
1650
if (typeof props.to === 'string') {
17-
hashFragment = props.to.split('#').slice(1).join('#');
51+
hash = props.to.split('#').slice(1).join('#');
1852
} else if (typeof props.to === 'object' && typeof props.to.hash === 'string') {
19-
hashFragment = props.to.hash.replace('#', '');
53+
hash = props.to.hash.replace('#', '');
54+
}
55+
if (hash !== '') {
56+
hashFragment = hash;
57+
hashLinkScroll();
2058
}
21-
if (hashFragment !== '') hashLinkScroll(hashFragment);
2259
}
2360
return <Link {...props} onClick={handleClick}>{props.children}</Link>;
2461
}

0 commit comments

Comments
 (0)