forked from u1ui/js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
markHashLinks.js
48 lines (43 loc) · 1.43 KB
/
markHashLinks.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* mark link, todo: loop nav elements, for now it only works with one nav */
var links = null;
var getLinks = function(){
if (links) return links;
var els = document.querySelectorAll('a[href]');
links = [];
for (var i=0,a; a=els[i++];) {
var matches = a.href.match(/#(.*)/);
if (!matches) continue;
var id = matches[1];
if (!id) continue;
var target = document.getElementById(id);
if (!target) continue;
links.push({a, target, id});
}
setTimeout(()=> links = null, 3000);
return links;
};
var listen = function(e){
var links = getLinks(), winner, i=0, link;
while (link=links[i++]) {
var pos = link.target.getBoundingClientRect();
if (pos.top > 140) break; // first target below viewport
winner = link;
}
winner && markLinksActivated(winner.id);
};
document.addEventListener('DOMContentLoaded',listen);
addEventListener('scroll',listen);
addEventListener('resize',listen);
var latestWinner;
function markLinksActivated(id){
if (latestWinner === id) return;
latestWinner = id;
var actives = document.querySelectorAll('.hashLinkActive');
for (var i=0,item; item=actives[i++];) item.classList.remove('hashLinkActive');
var links = getLinks();
for (i=0; item=links[i++];) {
item.id === id && item.a.classList.add('hashLinkActive');
}
}
addEventListener('pushstate',e=>markLinksActivated(location.hash));
//addEventListener('cms.navigator-navigated', e=>markLinksActivated(location.hash)); // todo: make onpopstate-polyfill