详解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 相关文章推荐
基于jquery的tab切换 js原理
Apr 01 Javascript
删除条目时弹出的确认对话框
Jun 05 Javascript
jQuery插件Validate实现自定义表单验证
Jan 18 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
Feb 14 Javascript
javascript中apply、call和bind的使用区别
Apr 05 Javascript
详解BootStrap中Affix控件的使用及保持布局的美观的方法
Jul 08 Javascript
微信小程序实现留言功能
Oct 31 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 Javascript
js实现多张图片每隔一秒切换一张图片
Jul 29 Javascript
详解解决小程序中webview页面多层history返回问题
Aug 20 Javascript
详解node和ES6的模块导出与导入
Feb 19 Javascript
Vue切换Tab动态渲染组件的操作
Sep 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
PHP Callable强制指定回调类型的方法
2016/08/30 PHP
Nginx环境下PHP flush失效的解决方法
2016/10/19 PHP
PHP文件后缀不强制为.php方法
2019/03/31 PHP
Javascript 继承实现例子
2009/08/12 Javascript
javascript 多级checkbox选择效果
2009/08/20 Javascript
由Javascript实现的页面日历
2011/11/04 Javascript
IE8的JavaScript点击事件(onclick)不兼容的解决方法
2013/11/22 Javascript
封装的dialog插件 基于bootstrap模态对话框的简单扩展
2016/08/10 Javascript
为jQuery-easyui的tab组件添加右键菜单功能的简单实例
2016/10/10 Javascript
详解Jquery EasyUI tree 的异步加载(遍历指定文件夹,根据文件夹内的文件生成tree)
2017/02/11 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
layui switch 开关监听 弹出确定状态转换的例子
2019/09/21 Javascript
layui实现给某一列加点击事件
2019/10/26 Javascript
[53:13]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-GAMING
2014/05/22 DOTA
[01:05:24]Ti4 冒泡赛第二天 iG vs NEWBEE 3
2014/07/15 DOTA
[28:42]Ti4正赛VG vs NEWBEE1
2014/07/19 DOTA
Python列表append和+的区别浅析
2015/02/02 Python
python3编码问题汇总
2016/09/06 Python
python制作爬虫爬取京东商品评论教程
2016/12/16 Python
python保存字典和读取字典的实例代码
2019/07/07 Python
Python with语句和过程抽取思想
2019/12/23 Python
python手写均值滤波
2020/02/19 Python
重写django的model下的objects模型管理器方式
2020/05/15 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
2021/02/02 Python
解决pytorch 保存模型遇到的问题
2021/03/03 Python
使用HTML和CSS实现的标签云效果(附demo)
2021/02/03 HTML / CSS
美国内衣第一品牌:Hanes(恒适)
2016/07/29 全球购物
自荐信的基本格式
2014/02/22 职场文书
美术指导助理求职信
2014/04/20 职场文书
保险专业求职信
2014/07/07 职场文书
小学师德师风演讲稿
2014/09/02 职场文书
2015年社区中秋节活动总结
2015/03/23 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书
戒赌保证书
2015/05/11 职场文书
合理缓解职场压力,让你随时保持最佳状态!
2019/06/21 职场文书
2019年圣诞节祝福语集锦
2019/12/25 职场文书