Angular学习笔记64:使用Render2安全操作DOM元素

在项目中有时候需要直接操作DOM,但是这样直接访问 DOM 会导致应用很容易受到在 XSS 攻击。所以并不建议直接访问 DOM。
在Angular 访问DOM 需要使用 Render2 来实现自定义渲染。

Renderer2类是Angular以服务的形式提供的抽象类,允许操作当前应用的元素,而不用直接访问最原始的DOM元素。

官方API

abstract class Renderer2 {
   
  abstract data: {
   ...}
  destroyNode: ((node: any) => void) | null
  abstract destroy(): void
  abstract createElement(name: string, namespace?: string): any
  abstract createComment(value: string): any
  abstract createText(value: string): any
  abstract appendChild(parent: any, newChild: any): void
  abstract insertBefore(parent: any, newChild: any, refChild: any): void
  abstract removeChild(parent: any, oldChild: any, isHostElement?: boolean): void
  abstract selectRootElement(selectorOrNode: any, preserveContent?: boolean): any
  abstract parentNode(node: any): any
  abstract nextSibling(node: any): any
  abstract setAttribute(el: any, name: string, value: string, namespace?: string): void
  abstract removeAttribute(el: any, name: string, namespace?: string): void
  abstract addClass(el: any, name: string): void
  abstract removeClass(el: any, name: string): void
  abstract setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void
  abstract removeStyle(el: any, style: string, flags?: RendererStyleFlags2): void
  abstract setProperty(el: any, name: string, value: any): void
  abstract setValue(node: any, value: string): void
  abstract listen(target: any, eventName: string, callback: (event: any) => boolean | void): () => void
}

使用一些常用的方法

创建一个Demo组件

使用命令:

ng g c operatingDOM

创建成功

wujiayudeMacBook-Pro:pages wjy$ ng g c operatingDOM
CREATE src/app/pages/operating-dom/operating-dom.component.less (0 bytes)
CREATE src/app/pages/operating-dom/operating-dom.component.html (32 bytes)
CREATE src/app/pages/operating-dom/operating-dom.component.spec.ts (671 bytes)
CREATE src/app/pages/operating-dom/operating-dom.component.ts (297 bytes)
UPDATE src/app/pages/pages.module.ts (2371 bytes)

在组件中注入 Render2

修改组件的类文件如下:

import {
   Component, OnInit, Renderer2} from '@angular/core';

@Component({
   
  selector: 'app-operating-dom',
  templateUrl: './operating-dom.component.html',
  styleUrls: ['./operating-dom.component.less']
})
export class OperatingDOMComponent implements OnInit {
   

  constructor(private render2: Renderer2) {
   
  }

  ngOnInit() {
   
  }

}

创建一个元素,将这个元素添加到组件模版已有的元素中

修改组件的模版文件如下:

<nz-divider nzText="Render2 操作DOM"></nz-divider>
<div #demo></div>
<button nz-button (click)="restDemoApi1()">createElement</button>

按钮的点击事件如下:

import {
   Component, ElementRef, OnInit, Renderer2, ViewChild} from '@angular/core';

@Component({
   
  selector: 'app-operating-dom',
  templateUrl: './operating-dom.component.html',
  styleUrls: ['./operating-dom.component.less']
})
export class OperatingDOMComponent implements OnInit {
   
  @ViewChild('demo') demoDom: ElementRef;

  constructor(private render2: Renderer2) {
   
  }

  ngOnInit() {
   
  }

  // createElement & appendChild & createText
  public restDemoApi1(): void {
   
    const divEle = this.render2.createElement('div');
    const textEle = this.render2.createText('hello Render2');
    this.render2.appendChild(divEle, textEle);
    this.render2.appendChild(this.demoDom.nativeElement, divEle);
  }
}

在这个方法中,通过 createElement 创建了一个 div 的元素,并通过 createText 创建了以一段文本节点, 将这段文本节点 通过 appendChild方法添加刚刚创建的 div 元素中,这里的div作为父元素, 文本节点作为子元素。并将添加了 文本节点 的div元素 添加到模版已经有的 demo 元素中。
从而点击的效果如下:

在这里插入图片描述

为DOM元素添加/删除 Attribute

在这里为之前的 div 元素增加 aria-hidden=“true” 的Attribute。

添加Attribute

修改模版文件:

<h1>Render2 操作DOM</h1>
<nz-divider nzText="创建一个DOM"></nz-divider>
<div #demo></div>
<button nz-button (click)="restDemoApi1()">createElement</button>

<nz-divider nzText="添加"></nz-divider>
<button nz-button (click)="handleSetAttribute()">添加特性</button>

修改类文件:

import {
   Component, ElementRef, OnInit, Renderer2, ViewChild} from '@angular/core';
import {
   NzNotificationService} from 'ng-zorro-antd';

@Component({
   
  selector: 'app-operating-dom',
  templateUrl: './operating-dom.component.html',
  styleUrls: ['./operating-dom.component.less']
})
export class OperatingDOMComponent implements OnInit {
   
  @ViewChild('demo') demoDom: ElementRef;

  constructor(private render2: Renderer2, private notification: NzNotificationService) {
   
  }

  ngOnInit() {
   
  }

  // createElement & appendChild & createText
  public restDemoApi1(): void {
   
    const divEle = this.render2.createElement('div');
    const textEle = this.render2.createText('hello Render2');
    this.render2.appendChild(divEle, textEle);
    this.render2.appendChild(
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值