इस लेख में मैं यह बताने जा रहा हूं कि एक बहुत ही सरल कोणीय निर्देश कैसे बनाया जाए जो किसी तत्व की दृश्यता स्थिति, या दूसरे शब्दों में, जब वह अंदर और बाहर जाता है, पर नज़र रखता है व्यूपोर्ट. मुझे आशा है कि यह एक अच्छा और शायद उपयोगी अभ्यास होगा!
ऐसा करने के लिए, हम इंटरसेक्शनऑब्जर्वर जावास्क्रिप्ट एपीआई का उपयोग करने जा रहे हैं जो आधुनिक ब्राउज़रों में उपलब्ध है।
हम इस तरह निर्देश का उपयोग करना चाहते हैं:
I'm being observed! Can you see me yet?
आउटपुट इस आकार का होगा:
type VisibilityChange = | { isVisible: true; target: HTMLElement; } | { isVisible: false; target: HTMLElement | undefined; };
अपरिभाषित लक्ष्य होने का मतलब होगा कि तत्व को DOM से हटा दिया गया है (उदाहरण के लिए, @if द्वारा)।
हमारा निर्देश केवल एक तत्व की निगरानी करेगा, यह DOM संरचना को नहीं बदलेगा: यह एक विशेषता निर्देश होगा।
@Directive({ selector: "[visibility]", standalone: true }) export class VisibilityDirective implements OnInit, OnChanges, AfterViewInit, OnDestroy { private element = inject(ElementRef); /** * Emits after the view is initialized. */ private afterViewInit$ = new Subject(); /** * The IntersectionObserver for this element. */ private observer: IntersectionObserver | undefined; /** * Last known visibility for this element. * Initially, we don't know. */ private isVisible: boolean = undefined; /** * If false, once the element becomes visible there will be one emission and then nothing. * If true, the directive continuously listens to the element and emits whenever it becomes visible or not visible. */ visibilityMonitor = input(false); /** * Notifies the listener when the element has become visible. * If "visibilityMonitor" is true, it continuously notifies the listener when the element goes in/out of view. */ visibilityChange = output (); }
ऊपर दिए गए कोड में आप देखते हैं:
और स्वाभाविक रूप से, हम DOM तत्व को हथियाने के लिए ElementRef को इंजेक्ट करते हैं, जिस पर हम अपना निर्देश लागू करते हैं।
मुख्य विधि लिखने से पहले, आइए निर्देश के जीवनचक्र का ध्यान रखें।
ngOnInit(): void { this.reconnectObserver(); } ngOnChanges(): void { this.reconnectObserver(); } ngAfterViewInit(): void { this.afterViewInit$.next(); } ngOnDestroy(): void { // Disconnect and if visibilityMonitor is true, notify the listener this.disconnectObserver(); if (this.visibilityMonitor) { this.visibilityChange.emit({ isVisible: false, target: undefined }); } } private reconnectObserver(): void {} private disconnectObserver(): void {}
अब यहाँ क्या होता है:
यह हमारे निर्देश का मूल है। हमारी रीकनेक्टऑब्जर्वर विधि अवलोकन शुरू करने वाली होगी! यह कुछ इस तरह होगा:
private reconnectObserver(): void { // Disconnect an existing observer this.disconnectObserver(); // Sets up a new observer this.observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { const { isIntersecting: isVisible, target } = entry; const hasChangedVisibility = isVisible !== this.isVisible; const shouldEmit = isVisible || (!isVisible && this.visibilityMonitor); if (hasChangedVisibility && shouldEmit) { this.visibilityChange.emit({ isVisible, target: target as HTMLElement }); this.isVisible = isVisible; } // If visilibilyMonitor is false, once the element is visible we stop. if (isVisible && !this.visibilityMonitor) { observer.disconnect(); } }); }); // Start observing once the view is initialized this.afterViewInit$.subscribe(() => { this.observer?.observe(this.element.nativeElement); }); }
मेरा विश्वास करें, यह उतना जटिल नहीं है जितना लगता है! यहाँ तंत्र है:
private disconnectObserver(): void { if (this.observer) { this.observer.disconnect(); this.observer = undefined; } }अंतिम कोड
type VisibilityChange = | { isVisible: true; target: HTMLElement; } | { isVisible: false; target: HTMLElement | undefined; }; @Directive({ selector: "[visibility]", standalone: true }) export class VisibilityDirective implements OnChanges, OnInit, AfterViewInit, OnDestroy { private element = inject(ElementRef); /** * Emits after the view is initialized. */ private afterViewInit$ = new Subject(); /** * The IntersectionObserver for this element. */ private observer: IntersectionObserver | undefined; /** * Last known visibility for this element. * Initially, we don't know. */ private isVisible: boolean = undefined; /** * If false, once the element becomes visible there will be one emission and then nothing. * If true, the directive continuously listens to the element and emits whenever it becomes visible or not visible. */ visibilityMonitor = input(false); /** * Notifies the listener when the element has become visible. * If "visibilityMonitor" is true, it continuously notifies the listener when the element goes in/out of view. */ visibilityChange = output (); ngOnInit(): void { this.reconnectObserver(); } ngOnChanges(): void { this.reconnectObserver(); } ngAfterViewInit(): void { this.afterViewInit$.next(true); } ngOnDestroy(): void { // Disconnect and if visibilityMonitor is true, notify the listener this.disconnectObserver(); if (this.visibilityMonitor) { this.visibilityChange.emit({ isVisible: false, target: undefined }); } } private reconnectObserver(): void { // Disconnect an existing observer this.disconnectObserver(); // Sets up a new observer this.observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { const { isIntersecting: isVisible, target } = entry; const hasChangedVisibility = isVisible !== this.isVisible; const shouldEmit = isVisible || (!isVisible && this.visibilityMonitor); if (hasChangedVisibility && shouldEmit) { this.visibilityChange.emit({ isVisible, target: target as HTMLElement }); this.isVisible = isVisible; } // If visilibilyMonitor is false, once the element is visible we stop. if (isVisible && !this.visibilityMonitor) { observer.disconnect(); } }); }); // Start observing once the view is initialized this.afterViewInit$.subscribe(() => { this.observer?.observe(this.element.nativeElement); }); } private disconnectObserver(): void { if (this.observer) { this.observer.disconnect(); this.observer = undefined; } } }
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3