详解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 data日期初始化的5种方法
Dec 29 Javascript
JS中使用Array函数shift和pop创建可忽略参数的例子
May 28 Javascript
JS 在指定数组中随机取出N个不重复的数据
Jun 10 Javascript
js实现简单的联动菜单效果
Aug 19 Javascript
基于jquery实现简单的手风琴特效
Nov 24 Javascript
jQuery validate插件submitHandler提交导致死循环解决方法
Jan 21 Javascript
JQuery的Pager分页器实现代码
May 03 Javascript
JQuery和HTML5 Canvas实现弹幕效果
Jan 04 Javascript
详解Angular 4.x NgIf 的用法
May 22 Javascript
layui radio性别单选框赋值方法
Aug 15 Javascript
JavaScript中的null和undefined用法解析
Sep 30 Javascript
Vue3.0写自定义指令的简单步骤记录
Jun 27 Vue.js
微信小程序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
老照片 - 几十年前的收音机与人
2021/03/02 无线电
PHP新手上路(九)
2006/10/09 PHP
php处理json时中文问题的解决方法
2011/04/12 PHP
关于PHP实现异步操作的研究
2013/02/03 PHP
PHP中的命名空间相关概念浅析
2015/01/22 PHP
PHP用正则匹配form表单中所有元素的类型和属性值实例代码
2017/02/28 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
2018/02/19 PHP
PHP实现随机发扑克牌
2020/04/22 PHP
跟着Jquery API学Jquery之一 选择器
2010/04/07 Javascript
defer属性导致引用JQuery的页面报“浏览器无法打开网站xxx,操作被中止”错误的解决方法
2010/04/27 Javascript
ExtJS4如何自动生成控制grid的列显示、隐藏的checkbox
2014/05/02 Javascript
javascript字符串与数组转换汇总
2015/05/26 Javascript
Jquery实现仿京东商城省市联动菜单
2015/11/19 Javascript
轻松掌握JavaScript享元模式
2016/08/27 Javascript
Vue分页组件实例代码
2017/04/17 Javascript
对vue v-if v-else-if v-else 的简单使用详解
2018/09/29 Javascript
jQuery 同时获取多个标签的指定内容并储存为数组
2018/11/20 jQuery
Angular CLI 使用教程指南参考小结
2019/04/10 Javascript
六个窍门助你提高Python运行效率
2015/06/09 Python
Python中的复制操作及copy模块中的浅拷贝与深拷贝方法
2016/07/02 Python
python+ffmpeg视频并发直播压力测试
2018/03/06 Python
Django+Ajax+jQuery实现网页动态更新的实例
2018/05/28 Python
Django 多语言教程的实现(i18n)
2018/07/07 Python
python将一组数分成每3个一组的实例
2018/11/14 Python
Python根据欧拉角求旋转矩阵的实例
2019/01/28 Python
python使用adbapi实现MySQL数据库的异步存储
2019/03/19 Python
python 通过可变参数计算n个数的乘积方法
2019/06/13 Python
Python Django 封装分页成通用的模块详解
2019/08/21 Python
python求平均数、方差、中位数的例子
2019/08/22 Python
python 制作简单的音乐播放器
2020/11/25 Python
ONLY德国官方在线商店:购买时尚女装
2017/09/21 全球购物
Java里面有没有全局变量?为什么?
2015/02/06 面试题
2013年入党人员的自我鉴定
2013/10/25 职场文书
党员四风问题对照检查材料思想汇报
2014/09/16 职场文书
Python爬虫进阶之Beautiful Soup库详解
2021/04/29 Python
springboot临时文件存储目录配置方式
2021/07/01 Java/Android