动态切换overflow属性时如何阻止页面自动滚动至顶部
问题根因
你遇到的滚动回顶并非overflow: hidden切换为overflow: auto的默认行为,核心原因是你的代码逻辑在切换滚动承载容器:
showScrollbar = false时,外层.showcase容器设置了固定高度+overflow: auto,是页面的滚动容器showScrollbar = true时,外层改为overflow: hidden不再承载滚动,内层.col-9改为固定高度+overflow: auto成为新的滚动容器
滚动容器变更时,原有容器的滚动偏移量会失效,就会出现页面回顶的现象。
方案1:保留原有逻辑,手动同步滚动位置
在切换类前后分别保存、恢复滚动位置即可,修改代码如下:
1. 修改 app.component.html 给对应元素加模板引用
<div class="navbar">For your reading pleasure</div> <!-- 外层容器加#outerContainer引用 --> <div #outerContainer class="container-fluid showcase" [ngClass]="showScrollbar ? 'showcase-no-scrollbar' : 'showcase-scrollbar'" > <div class="row justify-content-between"> <!-- 内层容器加#innerContainer引用 --> <div #innerContainer class="col-9" [attr.data-cy]="'showcase'" [ngClass]="showScrollbar ? 'showcase-scrollbar' : 'showcase-no-scrollbar'" > <!-- 原有内容省略 --> <button type="button" class="btn btn-primary" (click)="toggleNestedScrollbar()" > Toggle nested scrollbar </button> </div> <div class="col-3 showcase-course-content-sidebar" id="shepherd-body-showcase-course-content-sidebar" > test </div> </div> </div>
2. 修改 app.component.ts 补充滚动位置同步逻辑
import { Component, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { showScrollbar = false; // 获取两个容器的DOM引用 @ViewChild('outerContainer') outerContainer!: ElementRef<HTMLDivElement>; @ViewChild('innerContainer') innerContainer!: ElementRef<HTMLDivElement>; toggleNestedScrollbar() { // 切换前保存当前激活的滚动容器的滚动偏移量 const currentScroll = this.showScrollbar ? this.innerContainer.nativeElement.scrollTop : this.outerContainer.nativeElement.scrollTop; // 切换类状态 this.showScrollbar = !this.showScrollbar; // 等待Angular视图更新完成后,给新的滚动容器设置滚动偏移量 setTimeout(() => { if (this.showScrollbar) { this.innerContainer.nativeElement.scrollTop = currentScroll; } else { this.outerContainer.nativeElement.scrollTop = currentScroll; } }, 0); } }
方案2(更推荐):固定滚动容器,避免容器变更
直接固定内层为唯一滚动容器,外层永久设为overflow: hidden,切换时仅修改内层的overflow属性,从根源避免滚动容器变更带来的偏移量丢失问题,修改代码如下:
1. 修改 app.component.css
/* 外层固定样式,永久不承载滚动 */ .showcase { overflow: hidden; height: calc(100vh - 115px) !important; } .showcase-no-scrollbar { overflow-y: hidden; overflow-x: hidden; } .showcase-scrollbar { overflow-y: auto; overflow-x: hidden; overscroll-behavior: none; } .showcase-scrollbar::-webkit-scrollbar { width: 0.31rem; background: #f9fbfd; } .showcase-scrollbar::-webkit-scrollbar-thumb { background: #959da5 !important; }
2. 修改 app.component.html 移除外层的ngClass逻辑
<div class="navbar">For your reading pleasure</div> <!-- 外层去掉ngClass,固定样式 --> <div class="container-fluid showcase"> <div class="row justify-content-between"> <div class="col-9" [attr.data-cy]="'showcase'" [ngClass]="showScrollbar ? 'showcase-scrollbar' : 'showcase-no-scrollbar'" > <!-- 原有内容省略 --> </div> <!-- 侧边栏内容省略 --> </div> </div>
该方案无需修改ts逻辑,切换时无任何滚动抖动,性能更优。
内容的提问来源于stack exchange,提问作者methuselah
相关产品推荐
相关产品推荐

