Skip to content

Commit b43a87d

Browse files
committed
feat: autoscroll menu
implements #88
1 parent 4d14c01 commit b43a87d

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

lib/components/SideMenu/side-menu.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
5151
private $resourcesNav: any;
5252
private $scrollParent: any;
5353

54-
private firstChange = true;
55-
5654
constructor(specMgr:SpecManager, elementRef:ElementRef,
5755
private scrollService:ScrollService, private menuService:MenuService,
5856
optionsService:OptionsService, private detectorRef:ChangeDetectorRef, private marker:Marker) {
@@ -84,15 +82,12 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
8482

8583
//safari doesn't update bindings if not run changeDetector manually :(
8684
this.detectorRef.detectChanges();
87-
if (this.firstChange) {
88-
this.scrollActiveIntoView();
89-
this.firstChange = false;
90-
}
85+
this.scrollActiveIntoView();
9186
}
9287

9388
scrollActiveIntoView() {
9489
let $item = this.$element.querySelector('li.active, label.active');
95-
if ($item) $item.scrollIntoView();
90+
if ($item) $item.scrollIntoViewIfNeeded();
9691
}
9792

9893
activateAndScroll(item) {

lib/polyfills.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,35 @@ if (!IS_PRODUCTION) {
2828
Error.stackTraceLimit = Infinity;
2929
require('zone.js/dist/long-stack-trace-zone');
3030
}
31+
32+
interface Element {
33+
scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;
34+
};
35+
36+
if (!(<any>Element).prototype.scrollIntoViewIfNeeded) {
37+
(<any>Element).prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
38+
centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded;
39+
40+
var parent = this.parentNode,
41+
parentComputedStyle = window.getComputedStyle(parent, null),
42+
parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
43+
parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
44+
overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
45+
overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
46+
overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
47+
overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
48+
alignWithTop = overTop && !overBottom;
49+
50+
if ((overTop || overBottom) && centerIfNeeded) {
51+
parent.scrollTop = this.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
52+
}
53+
54+
if ((overLeft || overRight) && centerIfNeeded) {
55+
parent.scrollLeft = this.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
56+
}
57+
58+
if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
59+
this.scrollIntoView(alignWithTop);
60+
}
61+
};
62+
}

0 commit comments

Comments
 (0)