天天看點

8Angular中Dom操作:ViewChild,實作CSS3動畫

1:ngAfterViewInit

       通過原生JS擷取dom都是在dom加載完成後擷取,Angular中也一樣,那麼Angular中在哪裡擷取呢?應該在

ngAfterViewInit

裡操作,關于詳細資訊可以看官方文檔Angular生命周期函數,在ngOnInit裡擷取有時會失敗的,不妨測試一下。

       建立好項目後,添加home元件,home前台:

<h2>示範dom操作</h2>

<h4>1:通過原生js操作dom</h4>
<p class="blue">1)不要在ngOnInit裡擷取dom</p>
<div id="div1">
  我是div1
</div>
<div id="div2" *ngIf="flag">
  我是div2,有指令後在ngOnInit裡擷取不到dom節點
</div>
           

home背景的ngOnInit:

//ngOnInit裡隻是元件和指令初始化完成,并不是真正的dom加載完成
  ngOnInit() {

    
    let d1 = document.getElementById("div1");
    let d2 = document.getElementById("div2");
    d1.style.color = "gray";
    d2.style.border = "solid red 1px";
  }
           

然後看一下效果:

8Angular中Dom操作:ViewChild,實作CSS3動畫

可以看到是擷取不到的,擷取dom時,注意要在ngAfterViewInit方法裡擷取,該方法是視圖加載完成後觸發的方法。在html加入

<p class="blue">2)在ngAgterViewInit裡擷取dom</p>
<div id="div3">
  我是div3
</div>
<div id="div4" *ngIf="flag">
  我是div4
</div>
<hr />
           

然後在背景ngAfterViewInit方法裡:

//視圖加載完成後觸發此方法,在這裡可以擷取到dom
  ngAfterViewInit() {
    let d3 = document.getElementById("div3");
    let d4 = document.getElementById("div4");
    d3.style.color = "gray";
    d4.style.border = "solid red 1px";
  }
           

然後看看效果:

8Angular中Dom操作:ViewChild,實作CSS3動畫

2:通過ViewChild擷取dom

Angualr中就是通過ViewChild擷取dom的,首先,給dom起名字:

<h4>2通過ViewChild操作dom</h4>
	<div #div5>
  		我是div5
	</div>
<hr />
           

然後,在home.component.ts裡引入ViewChild(有的IDE當你敲ViewChild時會自動引入)

引入前:

import { Component, OnInit} from '@angular/core';
           

引入後:

import { Component, OnInit,ViewChild } from '@angular/core';
           

然後在OnInit裡:

@ViewChild("div5", { static: true }) d5: any;//擷取dom
           

本來按照視訊寫的是 @ViewChild(‘div5’) d5: any;但是報錯,IDE提示需要兩個參數,然後就搜最後就按上面的寫了,相當于把擷取到的節點指派給d5,然後就可以在ngAfterViewInit裡操作dom節點了

this.d5.nativeElement.style.color = "orange";
	//如果不知道通過Angular擷取dom怎麼設定style,可以直接console.log(this.d5),
	//看這是個什麼,有什麼屬性,然後就知道怎麼設定style了
           
8Angular中Dom操作:ViewChild,實作CSS3動畫

3:通過ViewChild擷取元件

ViewChild操作dom實際上是對原生js的封裝,ViewChild還可以擷取元件,調用元件的方法。那麼接下來就測試一下,再定義一個head元件,在home元件裡引入head元件時取名:

<app-head #head></app-head>
           

和操作dom一樣,然後@ViewChild擷取到元件,然後在anAfterViewInit裡就可以擷取元件執行個體然後調用元件的方法和屬性

head背景:

info: string = "我是元件head的屬性";
  fun() {
    alert("元件head的方法")
  }
           

然後html背景:

@ViewChild("head", { static: true }) head:any;//擷取元件
 //ngAfterViewInit裡加入
    this.head.fun();
    console.log(this.head.info);
           
8Angular中Dom操作:ViewChild,實作CSS3動畫

4:實作CSS3動畫

定義一個transition元件,然後在transition元件裡,為了看得更加清楚,定義兩個div,分别是移動前後的側邊欄

<div id="sidebar0">
  	移動前
	</div>
	<div id="sidebar">
	  這是移動後的側邊欄
	</div>
           

設定一下樣式

#sidebar0 {
  position: absolute;
  width: 400px;
  height: 200px;
  color: aqua;
  left: 70%;
  top: 0;
  border: 1px red dotted;
}
#sidebar {
  position: absolute;
  width: 400px;
  height: 200px;
  background-color: gray;
  color: aqua;
  left: 70%;
  top: 0;
  
  /*使用translate相對自身原始位置平移
    transform: translate裡面的兩個參數分别是x和y坐标,可以用像素機關也可以用自身的百分比*/
  transform: translate(0,100%);

  /*表示transform移動的過程一共3s*/
  transition:all 2s;
}
           

定義第一個按鈕移動側邊欄,綁定的點選方法如下:

show() {
    let d = document.getElementById("sidebar");
    console.log("before:"+d.style.transform);
    //注意translate(0px, 0px)這裡括号裡面有空格,字元串是嚴格比對空格的,不像css裡,可以控制台裡輸出d.style然後
    //找到transform屬性,複制過來看看
    d.style.transform = (d.style.transform == "translate(0px, 0px)") ? "translate(0, 100%)" : "translate(0px, 0px)";
    console.log("after:"+d.style.transform);
  }

           
8Angular中Dom操作:ViewChild,實作CSS3動畫

transform還有很多屬性,平移,旋轉等,需要的話可以去查

繼續閱讀