详解Angular如何正确的操作DOM


Posted in Javascript onJuly 06, 2018

无奈接手了一个旧项目,上一个老哥在Angular项目中大量使用了JQuery来操作DOM,真的是太不讲究了。那么如何优雅的使用Angular的方式来操作DOM呢?

获取元素

1、ElementRef  ---   A wrapper around a native element inside of a View.

在组件的 constructor中注入ElementRef,可以获取到整个组件元素的包裹。

@Component({
 selector: 'app-test-page',
 templateUrl: './test-page.component.html',
 styleUrls: ['./test-page.component.scss']
})
export class TestPageComponent implements OnInit {

 constructor(
 private el: ElementRef
 ) { }

 ngOnInit() {
 }

 getDomTest() {
 console.dir(this.el);
 }
}

详解Angular如何正确的操作DOM

ElementRef中的nativeElement即是组件最外层的DOM元素。再通过原生的DOM定位方式,即可获取到指定的selector元素。

getDomTest() {
 console.dir(this.el.nativeElement.querySelector('.test-get-dom')); // 获取指定的子元素
 }

2、@viewChild()  ---    You can use ViewChild to get the first element or the directive matching the selector from the  view DOM.

@viewChild可以获取指定的元素, 指定的方式可以是本地变量或者组件类型;

// HTML
<div class="tip-test-wrapper">
 // 本地变量绑定button按钮
 <button class="test-get-dom" #testdom (click)="getDomTest()">测试获取DOM</button>
 </div>

// Dialog组件
<app-dialog></app-dialog>


// ts
import { DialogComponent } from './../../common/components/dialog/dialog.component';


@Component({
 selector: 'app-test-page',
 templateUrl: './test-page.component.html',
 styleUrls: ['./test-page.component.scss']
})
export class TestPageComponent implements OnInit {
  // 通过本地变量获取元素 可通过read来指定获取的元素类型
 @ViewChild('testdom' , { read: ViewContainerRef }) viewcontainer: ViewContainerRef;
 @ViewChild('testdom') viewelement: ElementRef;

  // 通过组件类型来获取
 @ViewChild(DialogComponent) viewcontent: DialogComponent;

 constructor(
 private el: ElementRef
 ) { }

 ngOnInit() {
 }

 getDomTest() {
 // console.dir(this.el.nativeElement.querySelector('.test-get-dom'));
 console.dir(this.viewcontainer);
 console.dir(this.viewelement);
 console.dir(this.viewcontent);
 }
}

详解Angular如何正确的操作DOM

备注:ElementRef或者 @viewChild 获取元素,一定要在 ngAfterViewInit 周期之后再使用。

3、@viewChildren --   You can use ViewChildren to get the {@link QueryList} of elements or directives from theview DOM.

@viewChild会返回符合条件的第一个元素,如果需要获取多个符合条件的元素呢? @viewChildren会返回所有符合条件的元素的list。 指定selector的方式与@viewChild一致。

// 复制一个元素
 <div class="tip-test-wrapper">
 <button class="test-get-dom" #testdom (click)="getDomTest()">测试获取DOM</button>
 </div>
 <div class="tip-test-wrapper">
 <button class="test-get-dom" #testdom (click)="getDomTest()">测试获取DOM</button>
 </div>
</div>
<app-dialog></app-dialog>
<app-dialog></app-dialog>

// ts
import { DialogComponent } from './../../common/components/dialog/dialog.component';


@Component({
 selector: 'app-test-page',
 templateUrl: './test-page.component.html',
 styleUrls: ['./test-page.component.scss']
})
export class TestPageComponent implements OnInit {

 @ViewChild('testdom' , { read: ViewContainerRef }) viewcontainer: ViewContainerRef;
 @ViewChild('testdom') viewelement: ElementRef;
 @ViewChildren('testdom') viewelements: QueryList<any>;
 @ViewChild(DialogComponent) viewcontent: DialogComponent;
 @ViewChildren(DialogComponent) viewcontents: QueryList<DialogComponent>;

 constructor(
 private el: ElementRef
 ) { }

 ngOnInit() {
 }

 getDomTest() {
 // console.dir(this.el.nativeElement.querySelector('.test-get-dom'));
 // console.dir(this.viewcontainer);
 console.dir(this.viewelement);
 console.dir(this.viewelements);
 console.dir(this.viewcontent);
 console.dir(this.viewcontents);
 }

详解Angular如何正确的操作DOM

操作DOM  --- Renderer2

在获取dom之后,如何对dom进行操作呢?原生的domAPI是一种选择,但是Angular提供了更好的跨平台方式   Renderer2。

引入 Renderer2  , 然后在construct中注入。

import { Component, OnInit , ViewContainerRef , ElementRef , ViewChild, Renderer2 , ViewChildren, QueryList} from '@angular/core';

import { DialogComponent } from './../../common/components/dialog/dialog.component';


@Component({
 selector: 'app-test-page',
 templateUrl: './test-page.component.html',
 styleUrls: ['./test-page.component.scss']
})
export class TestPageComponent implements OnInit {

 @ViewChild('testdom' , { read: ViewContainerRef }) viewcontainer: ViewContainerRef;
 @ViewChild('testdom') viewelement: ElementRef;
 @ViewChildren('testdom') viewelements: QueryList<any>;
 @ViewChild(DialogComponent) viewcontent: DialogComponent;
 @ViewChildren(DialogComponent) viewcontents: QueryList<DialogComponent>;

 constructor(
 private render: Renderer2,
 private el: ElementRef
 ) { }

 ngOnInit() {
 }

 getDomTest() {
 // 修改元素颜色
 this.render.setStyle(this.viewelement.nativeElement , 'color' , 'red');
 }
}

renderer2提供了丰富的API供使用,如下:

详解Angular如何正确的操作DOM

总结

通过elementRef或者@viewChild @viewChildren获取元素,再通过renderer2提供的API来操作元素。不过记得在不要在 ngAfterViewInit 周期之前使用。通过Angular提供的方式,可以满足大部分的操作DOM的需求了。如果有特殊的场景,当然还是原生DOM撸起来呀

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS解决ie6下png透明的方法实例
Aug 02 Javascript
JavaScript数据结构与算法之栈详解
Mar 12 Javascript
javascript for-in有序遍历json数据并探讨各个浏览器差异
Nov 30 Javascript
原生js实现图片层叠轮播切换效果
Feb 02 Javascript
12个非常实用的JavaScript小技巧【推荐】
May 18 Javascript
jquery ajaxfileupload异步上传插件使用详解
Feb 08 Javascript
jquery实现tab键进行选择后enter键触发click行为
Mar 29 jQuery
vux uploader 图片上传组件的安装使用方法
May 15 Javascript
详解Angular中实现自定义组件的双向绑定的两种方法
Nov 23 Javascript
微信小程序制作表格的方法
Feb 14 Javascript
详解vue-cli3开发Chrome插件实践
May 29 Javascript
vue移动端使用appClound拉起支付宝支付的实现方法
Nov 21 Javascript
微信小程序WebSocket实现聊天对话功能
Jul 06 #Javascript
JavaScript实现的简单Tab点击切换功能示例
Jul 06 #Javascript
vue结合axios与后端进行ajax交互的方法
Jul 06 #Javascript
jQuery实现仿京东防抖动菜单效果示例
Jul 06 #jQuery
vue.js动画中的js钩子函数的实现
Jul 06 #Javascript
老生常谈JS中的继承及实现代码
Jul 06 #Javascript
vue.js使用v-if实现显示与隐藏功能示例
Jul 06 #Javascript
You might like
实现分十页分向前十页向后十页的处理
2006/10/09 PHP
dedecms 制作模板中使用的全局标记图文教程
2007/03/11 PHP
Look And Say 序列php实现代码
2011/05/22 PHP
PHP实现的曲线统计图表示例
2016/11/10 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
ThinkPHP 5.x远程命令执行漏洞复现
2019/09/23 PHP
CSS中一些@规则的用法小结
2021/03/09 HTML / CSS
跟我一起学写jQuery插件开发方法(附完整实例及下载)
2010/04/01 Javascript
在VS2008中使用jQuery智能感应的方法
2010/12/30 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
2014/08/11 Javascript
DOM基础教程之事件对象
2015/01/20 Javascript
jQuery包裹节点用法完整示例
2016/09/13 Javascript
node安装--linux下的快速安装教程
2017/03/21 Javascript
JavaScript数据结构之数组的表示方法示例
2017/04/12 Javascript
基于滚动条位置判断的简单实例
2017/12/14 Javascript
AngularJS发送异步Get/Post请求方法
2018/08/13 Javascript
ajaxfileupload.js实现上传文件功能
2019/04/19 Javascript
微信小程序 wxParse插件显示视频问题
2019/09/27 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
详解Vue 单文件组件的三种写法
2020/02/19 Javascript
在vue中created、mounted等方法使用小结
2020/07/21 Javascript
python线程池(threadpool)模块使用笔记详解
2017/11/17 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
2018/09/02 Python
解决Python3.5+OpenCV3.2读取图像的问题
2018/12/05 Python
Python基于opencv实现的简单画板功能示例
2019/03/04 Python
Python反爬虫伪装浏览器进行爬虫
2020/02/28 Python
python pyqtgraph 保存图片到本地的实例
2020/03/14 Python
pytorch随机采样操作SubsetRandomSampler()
2020/07/07 Python
SmartBuyGlasses美国官网:太阳眼镜和眼镜
2017/08/20 全球购物
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
英语专业毕业生自荐信
2013/10/28 职场文书
园林设计师自荐信
2013/11/18 职场文书
生日寿宴答谢词
2014/01/19 职场文书
早会开场白台词大全
2015/06/01 职场文书
《7的乘法口诀》教学反思
2016/02/18 职场文书
Nginx已编译的nginx-添加新模块
2021/04/01 Servers