详解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 CSS修改学习第六章 拖拽
Feb 19 Javascript
JavaScript this调用规则说明
Mar 08 Javascript
jQuery代码优化 遍历篇
Nov 01 Javascript
jquery.autocomplete修改实现键盘上下键自动填充示例
Nov 19 Javascript
浅析JavaScript中的同名标识符优先级
Dec 06 Javascript
JS Replace 全部替换字符的用法小结
Dec 24 Javascript
jquery实用技巧之输入框提示语句
Jul 28 Javascript
js oncontextmenu事件使用详解
Mar 25 Javascript
vue中如何动态绑定图片,vue中通过data返回图片路径的方法
Feb 07 Javascript
webpack@v4升级踩坑(小结)
Oct 08 Javascript
JS左右无缝轮播功能完整实例
May 16 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
Dec 06 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
php ignore_user_abort与register_shutdown_function 使用方法
2009/06/14 PHP
PHP Oauth授权和本地加密实现方法
2016/08/12 PHP
php json相关函数用法示例
2017/03/28 PHP
php array_map()函数实例用法
2021/03/03 PHP
Jquery 获取对象的几种方式介绍
2014/01/17 Javascript
JavaScript中匿名、命名函数的性能测试
2014/09/04 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
2015/02/11 Javascript
学习javascript面向对象 掌握创建对象的9种方式
2016/01/04 Javascript
微信小程序自定义select下拉选项框组件的实现代码
2018/08/28 Javascript
原生JS 实现的input输入时表格过滤操作示例
2019/08/03 Javascript
JavaScript实现联动菜单特效
2020/01/07 Javascript
vue-router之解决addRoutes使用遇到的坑
2020/07/19 Javascript
vue打包npm run build时候界面报错的解决
2020/08/13 Javascript
python实现保存网页到本地示例
2014/03/16 Python
跟老齐学Python之编写类之二方法
2014/10/11 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
python模块之paramiko实例代码
2018/01/31 Python
python opencv检测目标颜色的实例讲解
2018/04/02 Python
对Python中数组的几种使用方法总结
2018/06/28 Python
Python2.7环境Flask框架安装简明教程【已测试】
2018/07/13 Python
使用Python的Turtle绘制哆啦A梦实例
2019/11/21 Python
Python3批量创建Crowd用户并分配组
2020/05/20 Python
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
为您搜罗全球潮流時尚品牌:HBX
2019/12/04 全球购物
拖鞋店创业计划书
2014/01/15 职场文书
师范毕业生自我鉴定
2014/01/15 职场文书
夏季药店促销方案
2014/08/22 职场文书
2014年全国爱牙日宣传活动方案
2014/09/21 职场文书
端午节活动总结报告
2015/02/11 职场文书
数学考试作弊检讨书300字
2015/02/16 职场文书
2016教师学习教育法心得体会
2016/01/19 职场文书
公安忠诚教育心得体会
2016/01/23 职场文书
2016大学优秀学生干部事迹材料
2016/03/01 职场文书
详解CocosCreator消息分发机制
2021/04/16 Javascript
JavaScript组合继承详解
2021/11/07 Javascript