إنشاء مستمع للـ Scroll
يمكنك إنشاء مستمع الـ Scroll بهذه البساطة:
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Observable, map, shareReplay } from 'rxjs';
@Component({
selector: 'app-top-scroll',
templateUrl: './top-scroll.component.html',
styleUrls: ['./top-scroll.component.scss']
})
export class TopScrollComponent {
@ViewChild('btnBackToTop') btnBackToTop!: ElementRef<HTMLInputElement>;
@HostListener('window:scroll', ['$event'])
getScrollPosition(): number {
if (window.pageYOffset > 20) {
this.btnBackToTop.nativeElement.setAttribute('style', 'display: block;')
} else {
this.btnBackToTop.nativeElement.setAttribute('style', 'display: none;')
}
return window.pageYOffset;
}
backToTop() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches),
shareReplay()
);
constructor(public translateService: TranslateService,
private breakpointObserver: BreakpointObserver,
) { }
}
أما ملف الـ HTML:
<a #btnBackToTop id="btnBackToTop" style="z-index: 200;"
[matTooltip]="'TOOLTIPS.BACK_TO_TOP' | translate"
(click)="backToTop()" target="_blank"
[class]="(translateService.currentLang === 'ar')? (((isHandset$ | async) === true)?'btn bg-warn-y btn-floating bt-lg ar-btn-back-to-top f-24':'btn bg-warn-y btn-floating bt-lg ar-btn-back-to-top') : (((isHandset$ | async) === true)?'btn bg-warn-y btn-floating bt-lg en-btn-back-to-top f-24':'btn bg-warn-y btn-floating bt-lg en-btn-back-to-top')">
<i class="mdi mdi-arrow-up text-primary-color"></i>
<span *ngIf="(isHandset$ | async) === false"></span>
</a>
ملاحظة: قد تقع في مشكلة أنه لا يعمل الزر بشكل جيد، الحل في ملف الـ style.css الأساسي وهي إضافة الكود التالي:
html,
body {
// height: 100%;
max-width: 100% !important;
overflow-x: hidden !important;
}
scrollToTop() {
// this.viewportScroller.scrollToPosition([0, 0]);
// this.bodyElement.nativeElement.scroll(0, 0);
// window.scroll(0, 0);
// this.viewportScroller.scrollToPosition([0, 0], { behavior: 'instant' });
this.targetElement.nativeElement.scrollIntoView({ behavior: 'smooth' });
// this.smooth.smoothScrollToTop({ duration: 1000, easing: 'linear'});
}
الطريقة الأفضل كالتالي:
الـ TS
onScroll(event: any) {
const scrollPosition = event.target.scrollTop;
if (scrollPosition) {
// Perform actions based on scroll position
if (Number(scrollPosition) > 200) {
this.header._elementRef.nativeElement.setAttribute('style', 'position: fixed; width: 100%; top: 0px; z-index: 100;')
}else{
this.header._elementRef.nativeElement.setAttribute('style', 'display: none; position: none; width: 100%; top: 0px; z-index: 100;')
}
}
}
لا تنسى تعريف الـ toolbar بهذه الطريقة
@ViewChild('header') header: MatToolbar;
صفحة الـ HTML:
<mat-sidenav-content (scroll)="onScroll($event)">
<mat-toolbar #header style="display: none; position: fixed; width: 100%;
top: 0px; z-index: 100;" color="primary">
.....
الحل الأفضل للتنقل في الصفحة وبشكل مباشر:
scrollTo(section: any) {
const sectionHtml = document.querySelector('#' + section);
if (sectionHtml !== null) {
sectionHtml.scrollIntoView({ behavior: "smooth", block: "start",
inline: "nearest" });
}
}
هناك أيضاً:
<button #btnBackToTop style="z-index: 100 !important;"
*ngIf="scrollPosition > 200"
[matTooltip]="'TOOLTIPS.BACK_TO_TOP' | translate"
(click)="scrollTo('top')"
class="ar-btn-back-to-top f-25 animate__animated animate__fadeInUpBig">
<i class="f-25 mdi mdi-arrow-up"></i>
</button>
scrollPosition: number = 0;
@ViewChild('header') header: MatToolbar;
@ViewChild('btnBackToTop') btnBackToTop: ElementRef;
onScroll(event: any) {
const scrollPosition = event.target.scrollTop;
console.log(scrollPosition);
this.scrollPosition = scrollPosition;
if (this.scrollPosition) {
// Perform actions based on scroll position
if (Number(scrollPosition) > 200) {
this.header._elementRef.nativeElement.setAttribute('style',
'position: fixed; width: 100%; top: 0px; z-index: 100;');
} else {
this.header._elementRef.nativeElement.setAttribute('style',
'display: none; position: none; width: 100%; top: 0px; z-index: 100;');
}
} else {
}
}
تعليقات
إرسال تعليق