2017-03-09 10 views
2

角2では、要素を別の要素に対して絶対的に配置する必要があります。 jQueryUIでこれを行うには、jQueryUI .position()を使用します。https://api.jqueryui.com/1.8/position/角2他の要素を基準にして要素を配置する方法

私はAngular 2ディレクティブを作成しようとしましたが、ターゲット要素(ページのどこにでもあり得る)を参照する方法が見つかりません上/左/幅/高さの値。

また、理解していただきたいのは、Angular 2ではDOM操作を避けなければならないということです。nativeElementを使用せずにこの位置機能を実現できますか?

目的は、ヘルプ/ヒントテキストを要素の上に配置できるページの上にオーバーレイを作成できるようにすることです。このページは応答性が高いことに注意してください。これは、望ましい効果の一例です。

help overlay

+0

CSSを使用して1つのコンポーネントを別のコンポーネントの子として配置できますか? DOM操作は避けなければなりません。 – Askanison4

+0

わかりません。質問を更新しました。目標は、ヘルプ/ヒントテキストを要素の上に配置できるページの上にオーバーレイを作成できるようにすることです。 –

+0

答えはあなたに十分な時間を与えましたか? – Askanison4

答えて

1

ここには、より多くの作業が必要な大まかな実装があります。これは、Ionic 2環境で実装されることに注意してください。

概要は、オーバーレイおよびツールヒント/ヒントが含まれている「導入」コンポーネントを作成します。このコンポーネントをIonic 2ポップオーバーとして開くことを選択しました(Ionicはオーバーレイを自動的に追加します)。相対要素をパラメータとして導入コンポーネントに渡します。他の要素(ページ上)を基準にして要素を絶対的に配置するディレクティブを作成します。 scssで振りかける

重要:私の場合、ページには読み込みに時間がかかる画像があります。イメージが読み込まれるまで、位置データが正しくありませんでした。私は単に紹介ページを開く遅延タイマーを持って、今の

$(window).load(function() { 
}); 

:これは、jQueryのでは同じであるとしてラップするコマンドによって解決されます。

MY-position.ts

この指令は(ページ上の)別の基準素子に対して素子の相対的な左/トップ設定します。

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

/** 
* Inspired by jQuery position: https://api.jqueryui.com/1.8/position/ 
*/ 

@Directive({ 
    selector: '[my-position]', 
    host: { 
     '[style.position]': '"absolute"', 
    } 
}) 
export class MyPosition implements OnInit { 
    @Input('my-position') of: any; 
    @Input('my') myInput: string; 
    @Input('at') atInput: string; 
    @Input('offset') offsetInput: string; 

    my: string[]; 
    at: string[] 
    offset: string[]; 

    constructor(
     private element: ElementRef, 
     private renderer: Renderer 
    ) {} 

    ngOnInit() { 

     if (this.of.nativeElement) { 

      let top: number; 
      let left: number; 

      // Default inputs. 
      if (!this.myInput) { 
       this.myInput = 'top left'; 
      } 
      if (!this.atInput) { 
       this.atInput = 'top left'; 
      } 
      if (!this.offsetInput) { 
       this.offsetInput = '0 0'; 
      } 

      this.my = this.myInput.split(' '); 
      this.at = this.atInput.split(' '); 
      this.offset = this.offsetInput.split(' '); 

      // Get reference element position. 
      let rect = this.of.nativeElement.getBoundingClientRect(); 

      // Set new top/left values. 
      left = rect.left + parseInt(this.offset[0]); 
      top = rect.top + parseInt(this.offset[1]); 

      // Adjust top/left values for on element position. 
      if (this.at[0] == 'center') { 
       left += rect.width/2; 
      } 
      if (this.at[1] == 'center') { 
       top += rect.height/2; 
      } 

      // Position element. 
      this.renderer.setElementStyle(this.element.nativeElement, 'top', top + 'px'); 
      this.renderer.setElementStyle(this.element.nativeElement, 'left', left + 'px'); 
     } 
    } 
} 

introduction.html紹介ページにツールチップ/ヒントを追加します。 my-positionディレクティブを追加し、相対要素をパラメータとして渡します。位置パラメータを追加します(必要に応じて)。コンストラクタで

<div class="hint" [my-position]="hintRef1" my="left top" at="left top" offset="0 105">This is an app hint!</div> 

introduction.ts

取得hintRef1要素パラメータ。

constructor(
    public navCtrl: NavController, 
    public navParams: NavParams, 
    private viewController: ViewController 
) { 
    // Get elements (passed as parameters from page) to use as references (to position hints). 
    this.hintRef1 = navParams.get('hintRef1'); 
    this.hintRef2 = navParams.get('hintRef2'); 
    this.hintRef3 = navParams.get('hintRef3'); 
} 

home.html

要素(キャメルケースでなければならない)、例えばを参照する名前を追加

<div #hintRef1 ... 

home.ts

は(パラメータとして渡す)ホームページの参照要素を取得します。

// Pass position reference elements to introduction popover. 
@ViewChild('hintRef1') hintRef1; 
@ViewChild('hintRef2') hintRef2; 
@ViewChild('hintRef3') hintRef3; 

紹介ページにパラメータとして参照要素を渡します。

1

このplunkerを見てください:https://plnkr.co/edit/oB6QJzncNbMAe1sIfVQ8?p=preview

何をすべきことはあなたのオーバーレイのために特別にコンポーネントを作成し、あなたがメッセージを持っているしたい任意のコンポーネントにそれを追加します

@Component({ 
 
    selector: 'my-tooltip', 
 
    template: `<span>{{ Message }}</span>`, 
 
    styles: ['span { position: absolute; }'] 
 
}) 
 
export class Tooltip { 
 
    @Input() 
 
    public Message: string = ""; 
 
}

@Component({ 
 
    selector: 'my-basic-component', 
 
    template:`<div> 
 
       <my-tooltip [Message]="toolTipMessage"></my-tooltip> 
 
     
 
       Here is a block of text that I want to annotate 
 
      </div>`, 
 
    styles: ['div { position: relative; }'] 
 
}) 
 
export class BasicComponent { 
 
    toolTipMessage: string = "USEFUL INFO"; 
 
}

ツールチップコンポーネントが露出メッセージ文字列と<span>要素を有しています。 <span>は、CSSにposition: absoluteを使用して配置されており、そこからニーズに合わせて使用​​方法を設定できるはずです。

+0

このアプローチは理にかなっています。ツールチップhtmlは、単にhtmlページの一部です。しかし、私はこのアプローチを使用してオーバーレイ効果を達成する方法を見ることができません。サンプル画像を含むように質問を更新しました。 –

+0

ああ、そうです。その場合は、ツールチップコンポーネントの条件付きクラスを使用して実装します。アクティブなときは、高いzインデックスを与え、 'display:block'というスタイルになります。クラスが適用されていないときは非表示になります。これは理にかなっていますか?私は私のコンピュータに戻ってきたときに例を書くようにしようとしています – Askanison4

+1

私は要素htmlにツールチップを直接追加する考えが好きです。それは彼らを簡単に位置付けることができます。しかし、私の理解は、ツールチップが同じコンテナ要素内にある必要がある淡色の効果を作成することです。コンテナ要素はページ全体をcss不透明で覆う。不透明度:0.5。しかし明らかに、これは同じ問題につながります。つまり、どの要素を「任意の」要素に相対的に配置するかです。 –

3

私は別の答えとしてこれを追加しています。なぜなら、元の回答とは異なる何かをしているからです。

無防備状態のお詫びthis plunker、@ Aydus-Matthew。それはちょっと一緒に投げられました。

私は注入可能なoverlayクラスを作成しました。このクラスは、オーバーレイをオン/オフしたい場所、またはアプリケーション内のオーバーレイのステータスを確認する必要がある場所で使用できます。

これにより、属性スタイルをツールチップに使用して、ツールチップを表示する条件付きスタイルを追加することができます。

@Injectable() 
 
export class Overlay { 
 
    public IsVisible: boolean = false; 
 
    
 
    public Toggle(): void { 
 
    this.IsVisible = !this.IsVisible; 
 
    } 
 
}

次に、このようなツールチップコンポーネントでそれを使用します。うまくいけば、これはあなたがあなたのを解決する必要がある右の実装に得ることができます

import { Overlay } from './overlay'; 
 

 
@Component({ 
 
    selector: 'my-tooltip', 
 
    template: `<span [class.visible]="overlay.IsVisible">{{ Message }}</span>`, 
 
    styles: ['span { position: absolute; display: none; color: white; font-weight: bold } .visible { display: block } '], 
 
}) 
 
export class Tooltip { 
 
    @Input() 
 
    public Message: string = ""; 
 
    
 
    constructor (private overlay: Overlay) { } 
 
}

問題:

+0

この代替実装を検討するのに役立ちます。私たちの複雑なデザインのために要素を整列しようとすると、まだ複雑すぎます。 jQueryでこれを行うのは簡単だったでしょう。 –

+0

また、私のページの多くの要素は相対的な位置のコンテナーにあります。これにより、ツールチップがオーバーレイの上に正しく表示されなくなります。 –

関連する問題