无需window或DOM获取视口高度及元素偏移的Angular 4方案咨询
window/document Hey there! Awesome question—since you're already using Angular's ViewChild to reference your target element, we can stick to Angular's safe, native tools to get what you need without touching the global window or document objects directly. Let's break this down step by step:
1. Get Element's Distance to Viewport Top
This is actually super straightforward thanks to a native DOM method that lives directly on the element itself: getBoundingClientRect(). No document required at all—just your ViewChild reference.
First, make sure your ViewChild is set up correctly (Angular 4 doesn't need the static option):
import { Component, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-your-component', template: `<div #targetElement class="your-element"></div>` }) export class YourComponent { @ViewChild('targetElement') targetElement: ElementRef; getElementToViewportTop(): number { // Grab the element's bounding rectangle const elementRect = this.targetElement.nativeElement.getBoundingClientRect(); // elementRect.top gives the exact pixel distance from the element's top to the viewport's top return elementRect.top; } }
This method returns the precise distance you need, and since we're only interacting with the element reference provided by ViewChild, we're avoiding any direct document access.
2. Get Viewport Height Without window
Avoiding window.innerHeight can be done in a couple of safe ways that align with Angular's best practices. Here are two solid options:
Option A: Use Angular's DOCUMENT Injection (Less Strict)
If "no document" means you don't want to reference the global document directly (rather than avoiding it entirely), Angular provides a safe way to inject it via @angular/common:
import { Component, ViewChild, ElementRef, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; @Component({ selector: 'app-your-component', template: `<div #targetElement class="your-element"></div>` }) export class YourComponent { @ViewChild('targetElement') targetElement: ElementRef; constructor(@Inject(DOCUMENT) private doc: Document) {} getViewportHeight(): number { // documentElement.clientHeight reflects the viewport's height (excluding scrollbars) return this.doc.documentElement.clientHeight; } }
This is safer than accessing the global document because Angular handles the injection, which works better in server-side rendering contexts and avoids direct DOM manipulation warnings.
Option B: CSS Variable + Renderer2 (Strictly No window/document)
If you need to avoid document entirely, use a CSS variable to track viewport height, then read it with Angular's Renderer2 (the recommended way to interact with DOM styles):
First, add this to your global styles.css:
:root { --viewport-height: 100vh; }
Then in your component:
import { Component, ViewChild, ElementRef, Renderer2 } from '@angular/core'; @Component({ selector: 'app-your-component', template: `<div #targetElement class="your-element"></div>` }) export class YourComponent { @ViewChild('targetElement') targetElement: ElementRef; constructor(private renderer: Renderer2) {} getViewportHeight(): number { // Get the computed styles of your target element const computedStyles = this.renderer.getComputedStyle(this.targetElement.nativeElement); // Extract and parse the CSS variable value to a number return parseInt(computedStyles.getPropertyValue('--viewport-height').trim(), 10); } }
This approach never touches window or document—we're using Angular's Renderer2 to safely access styles, which keeps you compliant with Angular's security guidelines.
3. Set Element Height Safely
Now combine these methods to set your element's height, using Renderer2 instead of directly modifying the element's style (this avoids direct DOM manipulation risks):
setElementHeight(): void { const viewportHeight = this.getViewportHeight(); const elementTopOffset = this.getElementToViewportTop(); const desiredHeight = viewportHeight - elementTopOffset; // Use Renderer2 to set the height safely this.renderer.setStyle( this.targetElement.nativeElement, 'height', `${desiredHeight}px` ); }
You can call setElementHeight() whenever you need to update the height—like on component initialization (ngAfterViewInit()) or when the view resizes (use @HostListener('window:resize') if you don't mind the resize event, but it's still safer than accessing window directly).
内容的提问来源于stack exchange,提问作者skyleguy

