Javascript 如何在 Angular2 中获取(DOM)元素的宽度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39084250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get width of (DOM) Element in Angular2
提问by Kevin Regenrek
there a some similiar threads but I couldn't find a suitable answer for my needs. So that direct DOM access should be strictly avoided in angular2 I'm just wondering whats best practice for this.
有一些类似的主题,但我找不到适合我需求的答案。因此,在 angular2 中应该严格避免直接 DOM 访问,我只是想知道什么是最佳实践。
What I wan't to achieve is a resize of a element based on the current width.
我想要实现的是基于当前宽度调整元素的大小。
workitemresize.component.ts
workitemresize.component.ts
import { Directive, ElementRef, HostListener, Renderer, Input } from '@angular/core';
@Directive({
selector: '[workItemResize]'
})
export class WorkItemResizeDirective implements ngAfterViewInit {
private el: HTMLElement;
private renderer: Renderer;
constructor(el: ElementRef, public renderer: Renderer)
{
this.el = el.nativeElement;
this.renderer = renderer;
}
@HostListener('window:resize', ['$event.target'])
onResize()
{
this.resizeWorks();
}
ngAfterViewInit() {
this.resizeWorks();
}
private resizeWorks(): void {
this.renderer.setElementStyle(this.el, 'height', this.el.width); // <-- doesn't work I kow that this.el.width doesn't exist but just for demonstration purpose
this.renderer.setElementStyle(this.el, 'height', '500'); // <-- works
}
}
projects.template.html
项目.模板.html
<div class="posts row">
<div class="work-item col-xs-12 col-sm-6 col-no-padding" workItemResize *ngFor="let post of posts">
<!-- show some fancy image -->
<div class="img" [ngStyle]="{'background-image':'url('+post.better_featured_image.source_url+')'}"></div>
</div>
</div>
采纳答案by Günter Z?chbauer
I don't know a way to get the width from the host element without accessing nativeElement
but setting could be done like:
我不知道一种无需访问即可从宿主元素获取宽度的方法,nativeElement
但可以像这样进行设置:
@HostListener('window:resize', ['$event.target'])
onResize() {
this.resizeWorks();
}
@HostBinding('style.height.px')
elHeight:number;
private resizeWorks(): void {
this.elHeight = this.el.nativeElement.width;
}
If you can add an element inside your components template like
如果您可以在组件模板中添加一个元素,例如
<div style="width: 100%;" #div (window:resize)="elHeight = div.getBoundingClientRect()">
<!-- your template here -->
</div>
then this would work without direct DOM access at all (but not after init).
那么这将在没有直接 DOM 访问的情况下工作(但不是在 init 之后)。
回答by Imants Volkovs
I tried out @GünterZ?chbauer solution and refined it. You do not need HostListener to get bounds of div. Like with 'click' or other event (event)="function()", it will fire this function. I hope someone will find this helpful.
我尝试了@GünterZ?chbauer 解决方案并对其进行了改进。您不需要 HostListener 来获取 div 的边界。与“click”或其他事件 (event)="function()" 一样,它会触发此函数。我希望有人会发现这很有帮助。
<div #div (window:resize)="onResize(div.getBoundingClientRect())">
<!-- your template here -->
</div>
onResize() {
this.resizeWorks();
}
@HostBinding('style.height.px') elHeight:number;
private resizeWorks(): void {
this.elHeight = this.el.nativeElement.width;
}
(#div) - this is variable needed to get measurement target. It does not have to be same name as element, it can be any name.
(#div) - 这是获取测量目标所需的变量。它不必与元素同名,它可以是任何名称。
One more way to get element dimensions is to use ElementRef class from Angular Core, but then you have to find that child element which has width and height properties. I used this in Angular 2 Maps to get container width and height, but i found out that, using this method i had to find in element tree element which had these properties and it was second child of root element. It is more messy. ElementDimensions - is just a class with height and width which I made to contain those properties.
获取元素尺寸的另一种方法是使用 Angular Core 中的 ElementRef 类,但是您必须找到具有宽度和高度属性的子元素。我在 Angular 2 Maps 中使用它来获取容器的宽度和高度,但我发现,使用这种方法我必须在具有这些属性的元素树元素中找到它,它是根元素的第二个子元素。它更凌乱。ElementDimensions - 只是一个具有高度和宽度的类,我用它来包含这些属性。
<div (window:resize)="onResize()">
<!-- your template here -->
</div>
private getContainerDimensions(): ElementDimensions{
var rootElement = this.elementRef.nativeElement;
var childElement = rootElement.firstElementChild;
var contentElement = childElement.firstElementChild;
return {
height:contentElement.clientHeight,
width: contentElement.clientWidth
};
}
回答by Charleston
I tested this way and simply worked! It seems that binding did this job.
我以这种方式进行了测试并且简单地工作!似乎绑定完成了这项工作。
<div #foto [style.height.px]="foto.getBoundingClientRect().width / 2">
回答by Flavien Volken
You can get the width of the component itself if that one has a display property defined (such as 'block' in the example below). Note that you should be able to define this style (using dom shadowing):
如果组件定义了显示属性(例如下面示例中的“块”),则您可以获得组件本身的宽度。请注意,您应该能够定义此样式(使用 dom 阴影):
:host {
display:block;
}
If you are not using dom shadowing (Ionic 2-3):
如果您不使用 dom 阴影(Ionic 2-3):
my-component {
display:block;
}
Here is the controller (exposing the width as an observable):
这是控制器(将宽度暴露为可观察的):
import {AfterViewInit, Component, ElementRef, HostListener, Input} from '@angular/core';
import {Subject} from 'rxjs/Subject';
@Component({
selector: 'my-component',
template: '{{$width|async}}',
style: 'my-component {display: block;}'
})
export class MyComponent implements AfterViewInit {
@Input() public gridWidth: number;
private $width: Subject<number> = new Subject();
constructor(private elementRef: ElementRef) {
}
public ngAfterViewInit(): void {
this.emitWidth();
}
@HostListener('window:resize', ['$event.target'])
public onResize(): void {
this.emitWidth();
}
private emitWidth(): void {
this.$width.next(this.getWidth());
}
private getWidth(): number {
return this.getNativeElement().clientWidth;
}
private getNativeElement(): HTMLElement {
return this.elementRef.nativeElement;
}
}