在 Chrom 和所有其他浏览器(Safari 除外)中,当我滚动时,图片正确显示/更改并且文本也正确聚焦 --> 下一个滚动元素(段落)可见。
但在 Safari mac os 中,已经来不及了。当用户已经将整个段落滚动到显示屏顶部时,它会更改滚动图片并将文本设置为焦点。
这是一个带有打字稿的角度项目,滚动行为的逻辑如下所示:
打字稿
@Component({
templateUrl: './product-page.component.html',
styleUrls: ['./product-page.component.css'],
})
export class ProductPageComponent implements OnInit {
personImage: string = 'woman';
readonly scrollElements: ScrollElement[];
private _actualYScrollPosition: number = 0;
constructor(public commonService: CommonService, public resizeService: ResizeService) {
this.scrollElements = commonService.scrollElements;
}
ngOnInit(): void {
this.changeScrollImage();
}
@HostListener('window:scroll', ['$event'])
changeScrollImage(): void {
this._actualYScrollPosition = window.scrollY;
const element0 = document.querySelector('.scroll-element0') as HTMLElement;
const element1 = document.querySelector('.scroll-element1') as HTMLElement;
const element2 = document.querySelector('.scroll-element2') as HTMLElement;
const element3 = document.querySelector('.scroll-element3') as HTMLElement;
const element4 = document.querySelector('.scroll-element4') as HTMLElement;
const stoppScrolling = document.querySelector('.stoppScrollElements') as HTMLElement;
const elementList = [element0, element1, element2, element3, element4, stoppScrolling];
this.changeImageOnScroll(elementList);
}
private changeImageOnScroll(elementList: any[]): void {
const scrollElementImages = document.getElementsByClassName('visibleBoxes') as HTMLCollectionOf<HTMLElement>;
const startFirstScrollElement = elementList[0]?.offsetTop - elementList[0]?.offsetHeight;
const startLastScrollElement = elementList[elementList.length - 1]?.offsetTop - elementList[elementList.length - 2]?.offsetHeight;
for (let i = 0; i < elementList.length; i++) {
const startActualScrollElement = elementList[i]?.offsetTop - elementList[i]?.offsetHeight;
const startNextScrollElement = elementList[i + 1]?.offsetTop - elementList[i]?.offsetHeight;
if (this._actualYScrollPosition >= startActualScrollElement && this._actualYScrollPosition < startNextScrollElement) {
// set every text isFocused = false and every scroll-image display = none
for (let j = 0; j < this.scrollElements.length; j++) {
// when isColSmall = true, all is Focus always true --> every text will be focused and not blured out
if (!this.resizeService.isColSmall()) {
this.scrollElements[j].isFocused = false;
}
if (scrollElementImages[j]) {
scrollElementImages[j].style.display = 'none';
}
}
this.scrollElements[i].isFocused = true;
if (scrollElementImages[i]) {
scrollElementImages[i].style.display = 'block';
}
} else if (this._actualYScrollPosition < startFirstScrollElement || this._actualYScrollPosition >= startLastScrollElement) {
for (let j = 0; j < scrollElementImages.length; j++) {
scrollElementImages[j].style.display = 'none';
}
}
} // end forloop i
} // end method
} // end class
html --> 忽略
...
<div class="scroll-elements">
<div [ngClass]="{'container': resizeService.isColSmall() || resizeService.isColLarge()}">
<div class="row padding-5rem">
<div class="col-xl-5 col-md-12" [ngClass]="{'col-12' : resizeService.isColSmall()}">
<div *ngFor="let scrollElement of commonService.scrollElements">
<app-scroll-content class="scroll-element{{scrollElements.indexOf(scrollElement)}}"
[scrollElement]="scrollElement">
</app-scroll-content>
</div>
</div>
<div *ngIf="!resizeService.isColSmall()" class="col-1 gx-sm-0 gx-xl-5">
</div>
<div *ngIf="!resizeService.isColSmall()" class="col-xxl-6 col-lg-5 gx-md-5">
<div class="scroll-images position-sticky">
<ng-container *ngTemplateOutlet="officeManagementVisibleBox"></ng-container>
<ng-container *ngTemplateOutlet="networkVisibleBox"></ng-container>
<ng-container *ngTemplateOutlet="flexibilityVisibleBox"></ng-container>
<ng-container *ngTemplateOutlet="marketingVisibleBox"></ng-container>
<ng-container *ngTemplateOutlet="financeVisibleBox"></ng-container>
</div>
</div>
</div>
</div>
</div>
...
offsetHeight, offsetTop, scrollY