详解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 24 Javascript
一个js控制的导航菜单实例代码
Dec 03 Javascript
javascript弹出拖动窗口
Aug 11 Javascript
JavaScript学习笔记之检测客户端类型是(引擎、浏览器、平台、操作系统、移动设备)
Dec 03 Javascript
基于Echarts 3.19 制作常用的图形(非静态)
May 19 Javascript
jQuery Ajax File Upload实例源码
Dec 12 Javascript
实例讲解javascript实现异步图片上传方法
Dec 05 Javascript
解决vue.js 数据渲染成功仍报错的问题
Aug 25 Javascript
vue动态添加路由addRoutes之不能将动态路由存入缓存的解决
Feb 19 Javascript
turn.js异步加载实现翻书效果
Jul 25 Javascript
React学习之JSX与react事件实例分析
Jan 06 Javascript
实例讲解JavaScript 计时事件
Jul 04 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
Thinkphp5 微信公众号token验证不成功的原因及解决方法
2017/11/12 PHP
PHP保留两位小数的几种方法
2019/07/24 PHP
Laravel获取当前请求的控制器和方法以及中间件的例子
2019/10/11 PHP
appendChild() 或 insertBefore()使用与区别介绍
2013/10/11 Javascript
禁止IE用右键的JS代码
2013/12/30 Javascript
JavaScript通过正则表达式实现表单验证电话号码
2014/03/07 Javascript
JS实现超过长度限制后自动跳转下一款文本框的方法
2015/02/23 Javascript
详解AngularJS中的filter过滤器用法
2016/01/04 Javascript
jquery对dom节点的操作【推荐】
2016/04/15 Javascript
Jquery和BigFileUpload实现大文件上传及进度条显示
2016/06/27 Javascript
深入理解bootstrap框架之第二章整体架构
2016/10/09 Javascript
nodejs和php实现图片访问实时处理
2017/01/05 NodeJs
jquery实现点击a链接,跳转之后,该a链接处显示背景色的方法
2018/01/18 jQuery
基于vue.js中关于下拉框的值默认及绑定问题
2018/08/22 Javascript
关于javascript中的promise的用法和注意事项(推荐)
2021/01/15 Javascript
Linux下用Python脚本监控目录变化代码分享
2015/05/21 Python
python递归全排列实现方法
2018/08/18 Python
Python对象中__del__方法起作用的条件详解
2018/11/01 Python
Python编程在flask中模拟进行Restful的CRUD操作
2018/12/28 Python
python aiohttp的使用详解
2019/06/20 Python
python 数据生成excel导出(xlwt,wlsxwrite)代码实例
2019/08/23 Python
Django User 模块之 AbstractUser 扩展详解
2020/03/11 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
python 根据列表批量下载网易云音乐的免费音乐
2020/12/03 Python
英国最大的手表网站:The Watch Hut
2017/03/31 全球购物
美国餐厅用品和厨房设备批发网站:KaTom Restaurant Supply
2018/01/27 全球购物
Topshop法国官网:英国快速时尚品牌
2018/04/08 全球购物
Lookfantastic西班牙官网:英国知名美妆购物网站
2018/06/13 全球购物
软件测试面试题
2015/10/21 面试题
上班离岗检讨书
2014/01/27 职场文书
采购部经理岗位职责
2014/02/10 职场文书
诉讼代理人授权委托书
2014/04/08 职场文书
安全施工责任书
2014/08/25 职场文书
保险内勤岗位职责
2015/04/13 职场文书
三严三实·严以用权心得体会
2016/01/12 职场文书
解决MySQL添加新用户-ERROR 1045 (28000)的问题
2022/03/03 MySQL