详解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 相关文章推荐
Flash+XML滚动新闻代码 无图片 附源码下载
Nov 22 Javascript
JS小功能(操作Table--动态添加删除表格及数据)实现代码
Nov 28 Javascript
移除AngularJS下URL中的#字符的方法
Jun 19 Javascript
JSON简介以及用法汇总
Feb 21 Javascript
jQuery实现内容定时切换效果完整实例
Apr 06 Javascript
微信小程序 教程之WXML
Oct 18 Javascript
基于VUE选择上传图片并页面显示(图片可删除)
May 25 Javascript
JavaScript算法教程之sku(库存量单位)详解
Jun 29 Javascript
js图片上传的封装代码
Aug 01 Javascript
vue实现侧边栏导航效果
Oct 21 Javascript
vant组件中 dialog的确认按钮的回调事件操作
Nov 04 Javascript
用webAPI实现图片放大镜效果
Nov 23 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
dedecms模板标签代码官方参考
2007/03/17 PHP
PHP中全面阻止SQL注入式攻击分析小结
2012/01/30 PHP
php IP转换整形(ip2long)的详解
2013/06/06 PHP
PHP7.0安装笔记整理
2015/08/28 PHP
如何解决phpmyadmin导入数据库文件最大限制2048KB
2015/10/09 PHP
PHP 7.1中AES加解密方法mcrypt_module_open()的替换方案
2017/10/17 PHP
TP - 比RBAC更好的权限认证方式(Auth类认证)
2021/03/09 PHP
js的event详解。
2006/09/06 Javascript
js 禁用只读文本框获得焦点时的退格键
2010/04/25 Javascript
jQuery EasyUI API 中文文档 - EasyLoader 加载器
2011/09/29 Javascript
thinkphp中常用的系统常量和系统变量
2014/03/05 Javascript
js+html5实现canvas绘制椭圆形图案的方法
2016/05/21 Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
2016/09/14 Javascript
使用vue实现简单键盘的示例(支持移动端和pc端)
2017/12/25 Javascript
JS实现可切换图片的幻灯切换效果示例
2019/05/24 Javascript
解决layer.open后laydate失效的问题
2019/09/06 Javascript
vue的$http的get请求要加上params操作
2020/11/12 Javascript
[07:06]2018DOTA2国际邀请赛寻真——卫冕冠军Team Liquid
2018/08/10 DOTA
Django学习笔记之Class-Based-View
2017/02/15 Python
Python与Java间Socket通信实例代码
2017/03/06 Python
Python之Web框架Django项目搭建全过程
2017/05/02 Python
Python3中的列表生成式、生成器与迭代器实例详解
2018/06/11 Python
Python自动生成代码 使用tkinter图形化操作并生成代码框架
2019/09/18 Python
python socket通信编程实现文件上传代码实例
2019/12/14 Python
python:目标检测模型预测准确度计算方式(基于IoU)
2020/01/18 Python
Python终端输出彩色字符方法详解
2020/02/11 Python
python-sys.stdout作为默认函数参数的实现
2020/02/21 Python
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
自考自我鉴定范文
2013/10/30 职场文书
材料加工工程求职信
2014/02/19 职场文书
法学院毕业生求职信
2014/06/25 职场文书
2014年城管个人工作总结
2014/12/08 职场文书
幼儿园大班教师个人总结
2015/02/05 职场文书
英雄儿女观后感
2015/06/09 职场文书
2019年员工旷工保证书!
2019/06/28 职场文书
nginx搭建NFS网络文件系统
2022/04/14 Servers