Javascript 如何在Angular2中获取(DOM)元素的宽度

Javascript 如何在Angular2中获取(DOM)元素的宽度,javascript,angular,angular2-directives,Javascript,Angular,Angular2 Directives,有一些相似的线索,但我找不到合适的答案 为了我的需要。因此,应该严格避免直接访问DOM 在angular2中,我只是想知道这方面的最佳实践是什么 我不想实现的是根据当前宽度调整元素的大小 workitemresize.component.ts import{Directive,ElementRef,HostListener,Renderer,Input}来自“@angular/core”; @指示({ 选择器:“[workItemResize]” }) 导出类WorkItemResizeDire

有一些相似的线索,但我找不到合适的答案 为了我的需要。因此,应该严格避免直接访问DOM 在angular2中,我只是想知道这方面的最佳实践是什么

我不想实现的是根据当前宽度调整元素的大小

workitemresize.component.ts

import{Directive,ElementRef,HostListener,Renderer,Input}来自“@angular/core”;
@指示({
选择器:“[workItemResize]”
})
导出类WorkItemResizeDirective实现ngAfterViewInit{
私人el:HTMLElement;
私有渲染器:渲染器;
构造函数(el:ElementRef,公共呈现器:呈现器)
{ 
this.el=el.nativeElement;
this.renderer=渲染器;
}  
@HostListener('窗口:调整大小',['$event.target']))
onResize()
{ 
这个。resizeWorks();
}
ngAfterViewInit(){
这个。resizeWorks();
}
private resizeWorks():void{

this.renderer.setElementStyle(this.el,'height',this.el.width);//我不知道在不访问
nativeElement
的情况下如何从宿主元素获取宽度,但是可以像这样进行设置:

@HostListener('window:resize', ['$event.target']) 
onResize() { 
  this.resizeWorks();
}

@HostBinding('style.height.px')
elHeight:number;

private resizeWorks(): void {
  this.elHeight = this.el.nativeElement.width;
}
如果可以在组件模板中添加元素,如

<div style="width: 100%;" #div (window:resize)="elHeight = div.getBoundingClientRect()">
  <!-- your template here -->
</div>


如果没有直接的DOM访问(但在初始化之后就不行了)。

我尝试了@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;
}

onResize(){
这个。resizeWorks();
}
@HostBinding('style.height.px')elHeight:number;
private resizeWorks():void{
this.elHeight=this.el.nativeElement.width;
}
(#div)-这是获取度量目标所需的变量。它不必与元素同名,可以是任何名称

获取元素维度的另一种方法是使用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
    };
}

私有getContainerDimensions():ElementDimensions{
var rootElement=this.elementRef.nativeElement;
var childElement=rootElement.firstElementChild;
var contentElement=childElement.firstElementChild;
返回{
高度:contentElement.clientHeight,
宽度:contentElement.clientWidth
};
}

如果定义了显示特性(如下面示例中的“块”),则可以获取组件本身的宽度。请注意,您应该能够定义此样式(使用dom阴影):

如果未使用dom阴影(Ionic 2-3):

这是控制器(将宽度显示为可见):

import{AfterViewInit,Component,ElementRef,HostListener,Input}来自“@angular/core”;
从'rxjs/Subject'导入{Subject};
@组成部分({
选择器:“我的组件”,
模板:{{$width | async}}},
样式:“我的组件{display:block;}”
})
导出类MyComponent实现AfterViewInit{
@Input()公共网格宽度:number;
private$width:Subject=newsubject();
构造函数(私有elementRef:elementRef){
}
public ngAfterViewInit():void{
这个.emitWidth();
}
@HostListener('窗口:调整大小',['$event.target']))
public onResize():void{
这个.emitWidth();
}
私有宽度():void{
this.width.next(this.getWidth());
}
私有getWidth():编号{
返回此.getNativeElement().clientWidth;
}
私有getNativeElement():HTMLElement{
返回此.elementRef.nativeElement;
}
}

我用这种方法进行了测试,结果很简单!似乎是绑定完成了这项工作

<div #foto [style.height.px]="foto.getBoundingClientRect().width / 2">


Resize基于当前设置,听起来像是一个无休止的循环。不只是在init view和window.Resize之后。这应该很好@HostBinding和Renderer方法之间有什么显著的区别吗?我认为这两个版本都很好?哦,而且这个.el.nativeElement.width总是空的…所以我也在努力解决这个问题。那怎么办:this.renderer.setElementStyle(this.el'height',this.el.clientWidth+'px');它可以工作,但对我来说很奇怪…渲染器方法也很好。我发现
HostBinding
方法更容易阅读。您的问题是
this.el.width
而不是
this.el.nativeElement.width
。我假设
resizeWorks
在组件完全渲染之前被调用,或者尝试
getBoundingClientRect().width
.this.el引用了el.nativeElement(请参见构造函数)。好的,我坚持使用getBoundingClientRect().width。谢谢!最后一行代码:this.renderer.setElementStyle(this.el,'height',this.el.getBoundingClientRect().width+“px”);对。很抱歉,错过了那一行。因此
getBoundingClientRect()
成功了?这也是一个很好的解决方案!这非常聪明。但是Angular的更改检测会使浏览器在每次检测到更改时运行
getBoundingClientRect
方法。除非您特别希望以这种方式更新该div的样式,否则您应该将该宽度存储在.ts文件中,并仅更新它需要的时候。
:host {
    display:block;
}
my-component {
    display:block;
}
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;
    }
}
<div #foto [style.height.px]="foto.getBoundingClientRect().width / 2">