详解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)
Oct 31 Javascript
jquery操作复选框(checkbox)的12个小技巧总结
Feb 04 Javascript
node.js中的fs.stat方法使用说明
Dec 16 Javascript
深入浅析Extjs中store分组功能的使用方法
Apr 20 Javascript
javascript实现起伏的水波背景效果
May 16 Javascript
jquery ajax后台返回list,前台用jquery遍历list的实现
Oct 30 Javascript
canvas学习之API整理笔记(一)
Dec 29 Javascript
jQuery html表格排序插件tablesorter使用方法详解
Feb 10 Javascript
Vue 2.0中生命周期与钩子函数的一些理解
May 09 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
Aug 24 Javascript
详解如何在vscode里面调试js和node.js的方法步骤
Dec 24 Javascript
vue input输入框关键字筛选检索列表数据展示
Oct 26 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
支持数组的ADDSLASHES的php函数
2010/02/16 PHP
PHP使用Memcache时模拟命名空间及缓存失效问题的解决
2016/02/27 PHP
Yii 2.0如何使用页面缓存方法示例
2017/05/23 PHP
实例化php类时传参的方法分析
2020/06/05 PHP
用Jquery.load载入页面实现局部刷新
2014/01/22 Javascript
JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
2015/12/02 Javascript
你不知道的高性能JAVASCRIPT
2016/01/18 Javascript
仅9张思维导图帮你轻松学习Javascript 就这么简单
2016/06/01 Javascript
JS中的hasOwnProperty()和isPrototypeOf()属性实例详解
2016/08/11 Javascript
前端程序员必须知道的高性能Javascript知识
2016/08/24 Javascript
JS判断来路是否是百度等搜索索引进行弹窗或自动跳转的实现代码
2016/10/09 Javascript
Nodejs进阶:express+session实现简易登录身份认证
2017/04/24 NodeJs
Koa日志中间件封装开发详解
2019/03/09 Javascript
详解微信小程序-canvas绘制文字实现自动换行
2019/04/26 Javascript
JQuery中的常用事件、对象属性与使用方法分析
2019/12/23 jQuery
用webAPI实现图片放大镜效果
2020/11/23 Javascript
[03:32]2014DOTA2西雅图邀请赛 CIS外卡赛赛前black专访
2014/07/09 DOTA
[54:09]RNG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
python笔记(2)
2012/10/24 Python
谈谈如何手动释放Python的内存
2016/12/17 Python
在Python中append以及extend返回None的例子
2019/07/20 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
flask实现验证码并验证功能
2019/12/05 Python
使用before和:after伪类制作css3圆形按钮
2014/04/08 HTML / CSS
将"引用"作为函数参数有哪些特点
2013/04/05 面试题
医学检验专业个人求职信范文
2013/12/04 职场文书
通用求职信范文模板分享
2013/12/27 职场文书
火车来了教学反思
2014/02/11 职场文书
写求职信要注意什么问题
2014/04/12 职场文书
查摆问题对照检查材料
2014/08/28 职场文书
服务员岗位职责
2015/02/03 职场文书
办公用品质量保证书
2015/05/11 职场文书
会计手工模拟做账心得体会
2016/01/22 职场文书
java多态注意项小结
2021/10/16 Java/Android
Android实现获取短信验证码并自动填充
2023/05/21 Java/Android