事件处理程序中的滚动条可见性检测

时间:2017-03-28 07:12:25

标签: javascript angular dom

我有一个带有切换按钮的侧面板,用于窄/宽视图 在切换时,如果滚动条变得可见(溢出),它应该隐藏切换按钮。

我没有直接调用hideOrShowToggleBtn,而是添加了一个私有属性,我可以在ngAfterViewChecked中使用它来为每个事件调用一次,并且(希望)在更新视图之后。

但是,如果我切换到窄视图并且滚动条变为可见 - element.clientHeight element.scrollHeight相同且未检测到滚动条。
可能是因为ngAfterViewChecked过早发射。

是否有更好的方法来检测它并确保dom是最新的,而且在实际添加滚动条之前我没有检查旧视图?

@ViewChild('content') private mainContentDiv: ElementRef;

onSidebarToggleClick() {
    this.largeSidebar = !this.largeSidebar;
    this.sidebarToggled = true;
}

ngAfterViewChecked() {
    if (this.sidebarToggled) {
        this.hideOrShowToggleBtn();
    }
}

hideOrShowToggleBtn() {
    let element = this.mainContentDiv.nativeElement;

    let style = element.ownerDocument.defaultView.getComputedStyle(element, undefined);
    let hasScrollbar = (style.overflowY === 'auto' && element.clientHeight < element.scrollHeight);
    this.hideToggle = !hasScrollbar && !this.largeSidebar;
    this.sidebarToggled = false;
    this.changeDetectorRef.detectChanges();
}

HTML:

        <div class="sidebar-header">
            <i class="sidebar-header-toggle fa fa-2x cursor"
               (click)="onSidebarToggleClick()"
            ></i>
        </div>
        <div #content [ngClass]="{'sidebar-large': largeSidebar, 'sidebar-small': !largeSidebar }">

        </div>

Simplified Plunker: https://plnkr.co/edit/tv2quvCmzElZzidiRjTZ?p=preview

1 个答案:

答案 0 :(得分:0)

经过一段时间的尝试 - 这一切都归结为CSS3动画 - 角度没有意识到它。我有一个0.4s的过渡,所以dom实际上是在事件发生后0.4s更新的。

为了解决这个问题,我转而使用角度动画,这是一个简单的指南: https://coursetro.com/posts/code/25/Understanding-Angular-2-Animations-Tutorial

简而言之:

import { trigger, state, style, transition, animate, keyframes } from '@angular/animations';

animations: [
    trigger('slidePanel', [
        state('small', style({
            width: '300px'
        })),
        state('large', style({
            width: '570px'
        })),
        transition('small => large', animate('400ms ease-in')),
        transition('large => small', animate('400ms ease-out'))
    ]),
]

并将此添加到我的div我想要动画:

[@slidePanel]='state'

然后在我的点击处理程序中更新state属性值。