详解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 相关文章推荐
javascript 函数调用规则
Aug 26 Javascript
JS request函数 用来获取url参数
May 17 Javascript
调用jQuery滑出效果时闪烁的解决方法
Mar 27 Javascript
jquery 为a标签绑定click事件示例代码
Jun 23 Javascript
jQuery中prev()方法用法实例
Jan 08 Javascript
jquery实现动态改变div宽度和高度
May 08 Javascript
jquery背景跟随鼠标滑动导航
Nov 20 Javascript
jquery+json实现数据二级联动的方法
Nov 28 Javascript
微信小程序 用户数据解密详细介绍
Jan 09 Javascript
js前端导出Excel的方法
Nov 01 Javascript
JS脚本加载后执行相应回调函数的操作方法
Feb 28 Javascript
bootstrap中的导航条实例代码详解
May 20 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
PHP 引用文件技巧
2010/03/02 PHP
阿里对象存储OSS在laravel框架中的使用方法
2019/10/13 PHP
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
2008/11/03 Javascript
关于jQuery中的end()使用方法
2011/07/10 Javascript
javascript中取前n天日期的两种方法分享
2014/01/26 Javascript
javascript检测是否联网的实现代码
2014/09/28 Javascript
JavaScript的事件代理和委托实例分析
2015/03/25 Javascript
详解JavaScript表单验证(E-mail 验证)
2016/03/31 Javascript
jQuery EasyUI常用数据验证汇总
2016/09/18 Javascript
Dropzone.js实现文件拖拽上传功能(附源码下载)
2016/11/22 Javascript
JavaScript之json_动力节点Java学院整理
2017/06/29 Javascript
老生常谈javascript的面向对象思想
2017/08/22 Javascript
jfinal与bootstrap的登出实战详解
2017/11/27 Javascript
mockjs,json-server一起搭建前端通用的数据模拟框架教程
2017/12/18 Javascript
微信小程序中进行地图导航功能的实现方法
2018/06/29 Javascript
Vue 重置组件到初始状态的方法示例
2018/10/10 Javascript
vue中格式化时间过滤器代码实例
2019/04/17 Javascript
微信小程序通过js实现瀑布流布局详解
2019/08/28 Javascript
bootstrap+spring boot实现面包屑导航功能(前端代码)
2019/10/09 Javascript
微信小程序使用自定义组件导航实现当前页面高亮
2020/01/02 Javascript
原生JavaScript实现的无缝滚动功能详解
2020/01/17 Javascript
微信小程序实现多行文字滚动
2020/11/18 Javascript
Python中Django 后台自定义表单控件
2017/03/28 Python
Python 读取指定文件夹下的所有图像方法
2018/04/27 Python
Python实现的字典排序操作示例【按键名key与键值value排序】
2018/12/21 Python
Python遍历文件夹 处理json文件的方法
2019/01/22 Python
解决django后台样式丢失,css资源加载失败的问题
2019/06/11 Python
Python 实现文件读写、坐标寻址、查找替换功能
2019/09/11 Python
django中media媒体路径设置的步骤
2019/11/15 Python
Python:二维列表下标互换方式(矩阵转置)
2019/12/02 Python
Keras官方中文文档:性能评估Metrices详解
2020/06/15 Python
python中导入 train_test_split提示错误的解决
2020/06/19 Python
如何为DataGridView添加一个定制的Column Type
2014/01/21 面试题
公积金接收函格式
2015/01/30 职场文书
2015年中秋节主持词
2015/07/30 职场文书
MySQL分区以及建索引的方法总结
2022/04/13 MySQL