Scroll relatively to the first scrollable parent

This commit is contained in:
Roman Hotsiy 2015-11-29 19:18:01 +02:00
parent 02dbfddc39
commit d1fa83f018
5 changed files with 29 additions and 11 deletions

View File

@ -56,6 +56,8 @@ nav {
redoc {
display: block;
box-sizing: border-box;
height: 100%;
overflow: auto;
}
pre {

View File

@ -1,7 +1,6 @@
<div class="methods">
<div class="tag" *ng-for="#tag of data.tags">
<div class="tag-info" [attr.tag]="tag.name">
<a [attr.name]="tag.name"></a>
<h1> {{tag.name}} </h1>
<p *ng-if="tag.description" inner-html="{{ tag.description | marked }}"> </p>
</div>

View File

@ -4,6 +4,7 @@ import {RedocComponent, BaseComponent} from '../base';
import SchemaManager from '../../utils/SchemaManager';
import {NgZone, ChangeDetectionStrategy} from 'angular2/angular2';
import {redocEvents} from '../../events';
import scrollParent from 'scrollparent';
const CHANGE = {
NEXT : 1,
@ -29,10 +30,15 @@ export default class SideMenu extends BaseComponent {
super(schemaMgr);
this.zone = zone;
this.scrollParent = scrollParent(document.querySelector('side-menu'));
/*if (this.scrollParent.scrollHeight === this.scrollParent.clientHeight) {
this.scrollParent = window;
}*/
// for some reason constructor is not run inside zone
// as workaround running it manually
this.zone.run(() => {
this.bindScroll();
this.bindEvents();
});
this.activeCatIdx = 0;
this.activeMethodIdx = -1;
@ -41,23 +47,28 @@ export default class SideMenu extends BaseComponent {
redocEvents.bootstrapped.subscribe(() => this.hashScroll());
}
hashScroll() {
scrollY() {
return (this.scrollParent.scrollY != null) ? this.scrollParent.scrollY : this.scrollParent.scrollTop;
}
hashScroll(evt) {
let hash = window.location.hash;
if (!hash) return;
hash = hash.substr(1);
let tag = hash.split('/')[0];
let ptr = hash.substr(tag.length);
console.log(tag, ptr);
let el = this.getMethodEl(ptr, tag);
if (el) this.scrollTo(el);
if (evt) evt.preventDefault();
}
bindScroll() {
this.prevOffsetY = window.scrollY;
bindEvents() {
this.prevOffsetY = this.scrollY();
let view = document.querySelector('redoc');
this.viewBoxTop = view.offsetTop;
window.addEventListener('scroll', () => this.scrollHandler());
this.scrollParent.addEventListener('scroll', () => this.scrollHandler());
window.addEventListener('hashchange', evt => this.hashScroll(evt));
}
activateAndScroll(idx, methodIdx) {
@ -67,8 +78,12 @@ export default class SideMenu extends BaseComponent {
scrollTo(el) {
let subjRect = el.getBoundingClientRect();
let offset = window.scrollY + subjRect.top - this.viewBoxTop + 1;
window.scrollTo(0, offset);
let offset = this.scrollY() + subjRect.top - this.viewBoxTop + 1;
if (this.scrollParent.scrollTo) {
this.scrollParent.scrollTo(0, offset);
} else {
this.scrollParent.scrollTop = offset;
}
}
scrollToActive() {
@ -152,8 +167,8 @@ export default class SideMenu extends BaseComponent {
}
scrollHandler() {
let isScrolledDown = (window.scrollY - this.prevOffsetY > 0);
this.prevOffsetY = window.scrollY;
let isScrolledDown = (this.scrollY() - this.prevOffsetY > 0);
this.prevOffsetY = this.scrollY();
let stable = false;
while(!stable) {
let activeMethodHost = this.getCurrentMethodEl();

View File

@ -31,6 +31,7 @@
"json-schema-view-js": "npm:json-schema-view-js@^0.2.0",
"marked": "npm:marked@^0.3.5",
"reflect-metadata": "npm:reflect-metadata@^0.1.2",
"scrollparent": "npm:scrollparent@^0.1.0",
"swagger-parser": "npm:swagger-parser@^3.3.0",
"zone.js": "npm:zone.js@^0.5.7"
},

View File

@ -52,6 +52,7 @@ System.config({
"json-schema-view-js": "npm:json-schema-view-js@0.2.0",
"marked": "npm:marked@0.3.5",
"reflect-metadata": "npm:reflect-metadata@0.1.2",
"scrollparent": "npm:scrollparent@0.1.0",
"swagger-parser": "npm:swagger-parser@3.3.0",
"systemjs/plugin-json": "github:systemjs/plugin-json@0.1.0",
"zone.js": "npm:zone.js@0.5.8",