详解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 相关文章推荐
放弃用你的InnerHTML来输出HTML吧 jQuery Tmpl不详细讲解
Apr 20 Javascript
select、radio表单回显功能实现避免使用jquery载入赋值
Jun 08 Javascript
使用jQuery实现返回顶部
Jan 26 Javascript
jQuery实现购物车计算价格功能的方法
Mar 25 Javascript
JavaScript中split() 使用方法汇总
Apr 17 Javascript
Jquery插件easyUi实现表单验证示例
Dec 15 Javascript
微信小程序 开发之快递查询功能的实现
Jan 09 Javascript
详解用webpack2搭建angular2的项目
Jun 22 Javascript
原生js实现简单的模态框示例
Sep 08 Javascript
echarts整合多个类似option的方法实例
Jul 10 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
Jun 02 Javascript
Element MessageBox弹框的具体使用
Jul 27 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
Windows下的PHP5.0安装配制详解
2006/09/05 PHP
PHP数据库调用类调用实例(详细注释)
2012/07/12 PHP
Yii使用find findAll查找出指定字段的实现方法
2014/09/05 PHP
Codeigniter中集成smarty和adodb的方法
2016/03/04 PHP
php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法
2016/10/12 PHP
php格式文件打开的四种方法
2018/02/24 PHP
javascript中的location用法简单介绍
2007/03/07 Javascript
探寻Javascript执行效率问题
2014/11/12 Javascript
jQuery实现鼠标滚轮动态改变样式或效果
2015/01/05 Javascript
深入理解JavaScript系列(30):设计模式之外观模式详解
2015/03/03 Javascript
详解jQuery中的deferred对象的使用(一)
2016/05/27 Javascript
浅谈原生JS实现jQuery的animate()动画示例
2017/03/08 Javascript
vue cli2.0单页面title修改方法
2018/06/07 Javascript
使用vue点击li,获取当前点击li父辈元素的属性值方法
2018/09/12 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
js事件触发操作实例分析
2019/06/21 Javascript
如何在wxml中直接写js代码(wxs)
2019/11/14 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
2020/07/11 Javascript
[46:04]Liquid vs VP Supermajor决赛 BO 第四场 6.10
2018/07/05 DOTA
python安装PIL模块时Unable to find vcvarsall.bat错误的解决方法
2016/09/19 Python
详解用python实现简单的遗传算法
2018/01/02 Python
Python 文本文件内容批量抽取实例
2018/12/10 Python
解决python flask中config配置管理的问题
2019/07/26 Python
使用Django搭建一个基金模拟交易系统教程
2019/11/18 Python
pycharm如何设置官方中文(如何汉化)
2020/12/29 Python
CSS3 background-image颜色渐变的实现代码
2018/09/13 HTML / CSS
澳大利亚在线家具店:Luxo Living
2019/03/24 全球购物
Oracle性能调优原则
2012/05/03 面试题
事业单位个人应聘自荐信
2013/09/21 职场文书
怎样写演讲稿
2014/01/04 职场文书
高三英语教学反思
2014/01/13 职场文书
服务员岗位职责
2014/01/29 职场文书
师范教师专业大学生职业生涯规划范文
2014/03/02 职场文书
2015年专项整治工作总结
2015/04/03 职场文书
火烧圆明园观后感
2015/06/03 职场文书
深度好文:50条没人告诉你的人生经验,句句精辟
2019/08/22 职场文书