2017-05-19 20 views
1

あなたはngStyleをに設定して、の要素のスタイルを設定することができます。しかし、どうすればいいですかの要素のスタイルを取得します(つまり、ブラウザによってレンダリングされるデフォルトのスタイル)。AngularでDOM要素のスタイルを取得するには?

このコードは動作しますが、私は何をしようとしている表現していません:

<p>TEXT</p> 
width of TEXT element is {{textElement.width}} 
height of TEXT element is {{textElement.height}} 

は、私が(ブラウザがしたいしかし、それに幅や高さを告げず、)p要素が正常にレンダリングしたいです。しかし、レンダリングされた幅と高さが何であるかを知りたい。これをキャプチャするにはどうすれば結構ですか?

EDIT:幅と高さで何をしたいのかと尋ねた人もいます。私がしたいことは次のようなものです:

<p *ngIf="!isEditing">{{myText}}</p> 
<textarea *ngIf="isEditing" [(ngModel)]="myText"></textarea> 

デフォルトでは、pが表示され、textareaは表示されません。ユーザーが編集モードに入ると、pはtextareaに置き換えられます。テキストエリアの幅と高さをpに合わせて設定して、遷移がシームレスに見えるようにしたかったのです。これを行うより良い方法はありますか?

+0

あなたがそれらを得れば、幅と高さで行うことを計画していますか? –

+1

[角2:ディレクティブとコンポーネント内で要素の幅と高さを取得する方法は?](http://stackoverflow.com/questions/39813269/angular-2how-to-get-elements-width-height-within-ディレクティブとコンポーネント) –

+0

このようなものを試してみてください.... angle.element(document.querySelector( '#lilogin'))。removeClass( 'active'); – geminiousgoel

答えて

2

このディレクティブが適用されているネイティブDOM要素にアクセスできるディレクティブを使用するのが最善の方法です。その後、DOMがAfterViewInitフックでレンダリングされるまで待ってから、getComputedStyleメソッドを使用して、計算されたスタイルをすべて取得します。

import { Directive, ElementRef } from '@angular/core'; 

@Directive({ 
    selector: '[style-getter]' 
}) 

export class StyleGetter { 
    constructor(public el: ElementRef) {} 

    ngOnChanges() { 
    setTimeout(() => { 
     let styles = getComputedStyle(this.el.nativeElement); 
     console.log(styles.offsetWidth); 
    }) 
    } 

    ngAfterViewInit() { 
    let styles = getComputedStyle(this.el.nativeElement); 
     console.log(styles.offsetWidth); 
    } 
} 

入力バインディングが変更されたとき、多くの場合、DOMが再レンダリングされるので、あなたはまた、おそらくngOnChangesフックにフックする必要があります。 setTimeoutを使用すると、すべてのスタイルが計算されDOMがレンダリングされるまで待つことができます。

ので、あなたはまた、offsetWidth代わりのwidthを使用する必要があります。el.style.width はちょうどJavaScriptと でelement.styleで定義された幅プロパティがない返しながら、計算された要素の幅を返しますoffsetWidth

実際の要素の寸法を反映します。

続きを読むhere

+0

こんにちは!あなたは 'ngOnChanges'フックを意味しましたか? – yurzui

+0

@yurzui、ありがとう) –

1

最善の方法はこれを行わないことです。

ブラウザは、HTMLとCSSによって駆動されるリビング向けのレイアウトです。これらは、メディアクエリ、フレックスボックスなど、レイアウトを制御するための豊富な機能を提供します。

要素の高さにアクセスし、その上でこの要素を調整するか、またはこの要素をそこに移動すると、滑りやすい斜面があります。それを知る前に、ブラウザがあなたのために行うように設計されたレイアウト作業の多くを再作成してやり直すことになります。

実際に高さを取得したい場合は、他の回答に記載されているように、それを行う方法はもちろんあります。しかし、この道を始める前に、あなたは本当にしたいと思っている必要があり、必要があることを確認する必要があります。

あなたがそれを取得した後に身長をどのようにしたいのかという具体的な例を提示すると、多くの角度/ TSコードなしで同じことを達成するための多くの方法を提案する可能性があります。

あなたがテキストエリアが<p>を交換して欲しいものを達成するために、あなたはこの試みることができる:私はあなたのコードを見ることで把握することができます確信しているとして

let editing = false; 
 

 
function toggle() { 
 
    document.getElementById('div').classList.toggle('editing', editing = !editing); 
 
}
div { border: 1px solid gray; position: relative; } 
 

 
textarea { 
 
    display: none; 
 
    height: 100%; width: 100%; 
 
    position: absolute; top: 0; left: 0; 
 
} 
 

 
.editing textarea { display: block; } 
 
.editing p { visibility: hidden; }
<p><button onclick="toggle()">Toggle editing</button></p> 
 

 
<div id="div"> 
 
    <p> 
 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 
 
    </p> 
 
    
 
    <textarea></textarea> 
 

 
</div>

は、アプローチはptextareaの両方をdivに入れることです。 divのサイズは、pのサイズによって決まります。 textareaは、divと完全に一致するように絶対的に配置されています。編集モードでは、pvisibility: hidden;に設定されていますが、レイアウト内の位置/サイズは維持されていますが非表示になっており、textareadisplay: block;に設定されています。アンギュラするようになって

、および同じCSSを使用して、これは次のようになります。

// component 
editable = false; 

// template 
<p><button (click)="editable = !editable">Toggle editing</button></p> 

<div id="div" [class.editable]="editable"> 
    <p>{{myText}}</p> 
    <textarea [(ngModel)]="myText"></textarea> 
</div> 
+0

私は何をしようとしているのかを編集しました。幅と高さにアクセスするよりも良い方法はありますか? –

+0

これは役に立ちますが、問題が発生しました。私はまた、テキストを複数列のフォーマット、すなわち、並べて欲しい。 divのスタイルに "column-width:8em"を追加するなどしてください。テキストエリアは、テキストと同じ動作を行い、列に配置する必要があります。しかし、現時点では、テキスト領域は、列レイアウトをまったく尊重することなく、トグル時にdiv全体を単にカバーします。どのようにテキスト領域を列のレイアウトに合わせることができますか? –

+0

@RayZhang私は、テキストエリアをどのようにしても列に配置することは不可能ではないと思います。これは、テキストエリアの仕組みではありません。その場合は、 'contentEditable'を試してみてください。 –

関連する問題