fix menu sync positioning

This commit is contained in:
Roman Hotsiy 2015-11-26 23:30:13 +02:00
parent 96418ba54d
commit 32681bdfba

View File

@ -10,6 +10,12 @@ const CHANGE = {
INITIAL : 0 INITIAL : 0
}; };
const INVIEW_POSITION = {
ABOVE : 1,
BELLOW: -1,
INVIEW: 0
};
@RedocComponent({ @RedocComponent({
selector: 'side-menu', selector: 'side-menu',
providers: [SchemaManager], providers: [SchemaManager],
@ -26,7 +32,6 @@ export default class SideMenu extends BaseComponent {
this.zone.run(() => { this.zone.run(() => {
this.bindScroll(); this.bindScroll();
}); });
this.activeCatIdx = 0; this.activeCatIdx = 0;
this.activeMethodIdx = -1; this.activeMethodIdx = -1;
this.prevOffsetY = null; this.prevOffsetY = null;
@ -34,10 +39,11 @@ export default class SideMenu extends BaseComponent {
bindScroll() { bindScroll() {
this.prevOffsetY = window.scrollY; this.prevOffsetY = window.scrollY;
let view = document.querySelector('redoc');
this.viewBoxTop = view.offsetTop;
window.addEventListener('scroll', () => this.scrollHandler()); window.addEventListener('scroll', () => this.scrollHandler());
} }
activateAndScroll(idx, methodIdx) { activateAndScroll(idx, methodIdx) {
this.activate(idx, methodIdx); this.activate(idx, methodIdx);
this.scrollToActive(); this.scrollToActive();
@ -45,7 +51,7 @@ export default class SideMenu extends BaseComponent {
scrollToActive() { scrollToActive() {
let subjRect = this.getMethodEl().getBoundingClientRect(); let subjRect = this.getMethodEl().getBoundingClientRect();
let offset = window.scrollY + subjRect.top; let offset = window.scrollY + subjRect.top - this.viewBoxTop;
window.scrollTo(0, offset); window.scrollTo(0, offset);
} }
@ -111,6 +117,18 @@ export default class SideMenu extends BaseComponent {
return document.querySelector(selector); return document.querySelector(selector);
} }
/* returns 1 if element if above the view, 0 if in view and -1 below the view */
getElementInViewPos(el) {
if (Math.floor(el.getBoundingClientRect().top) > this.viewBoxTop) {
return INVIEW_POSITION.ABOVE;
}
if (el.getBoundingClientRect().bottom <= this.viewBoxTop) {
return INVIEW_POSITION.BELLOW;
}
return INVIEW_POSITION.INVIEW;
}
scrollHandler() { scrollHandler() {
let isScrolledDown = (window.scrollY - this.prevOffsetY > 0); let isScrolledDown = (window.scrollY - this.prevOffsetY > 0);
this.prevOffsetY = window.scrollY; this.prevOffsetY = window.scrollY;
@ -118,12 +136,12 @@ export default class SideMenu extends BaseComponent {
while(!stable) { while(!stable) {
let activeMethodHost = this.getMethodEl(); let activeMethodHost = this.getMethodEl();
if (!activeMethodHost) return; if (!activeMethodHost) return;
var elementInViewPos = this.getElementInViewPos(activeMethodHost);
if(isScrolledDown && activeMethodHost.getBoundingClientRect().bottom <= 0 ) { if(isScrolledDown && elementInViewPos === INVIEW_POSITION.BELLOW) {
stable = this.changeActive(CHANGE.NEXT); stable = this.changeActive(CHANGE.NEXT);
continue; continue;
} }
if(!isScrolledDown && Math.floor(activeMethodHost.getBoundingClientRect().top) > 0 ) { if(!isScrolledDown && elementInViewPos === INVIEW_POSITION.ABOVE ) {
stable = this.changeActive(CHANGE.BACK); stable = this.changeActive(CHANGE.BACK);
continue; continue;
} }