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