我知道有一些类似的问题,但没有一个回答我的问题。
基本上,什么是正确的操作DOM的正确方法,说我有这个。
html
<button id="buy-now">BUY NOW</button>
,当您单击按钮时,我希望按钮变为紫色,因此在纯JavaScript中,您会编写类似
javascript
changeColour() {
const b = document.getElementById('buy-now');
b.style.backgroundColor = 'purple';
}
现在在Angular中,我一直采用这种方式,但是最近发现有人说这是不正确的?
按角度操作DOM的正确方法是什么,我将如何重写示例以反映此更正的方法?
任何帮助将不胜感激!
编辑
要清楚,我知道在Angular中我可以做到
HTML
<button (click)="changeColour()" id="buy-now">BUY NOW</button>
TS文件
changeColour() {
const b = <HTMLElement>document.querySelector('#buy-now');
b.style.backgroundColour = 'purple'
}
但这是操纵dom的合适方法吗?
更改按钮颜色只是一个简单的例子,对于任何类型的DOM操作而言,我的意思都是
谢谢
答案 0 :(得分:4)
对文档美学的任何更改,例如页面导航(routing)
,项目选择(ngIf)
,循环迭代(ngFor)
等,都是DOM Manipulation
。它可以由property
驱动,也可以由event
触发或reference
处理。
Angular提供了多种处理DOM Manipulation
的方法。
EVENT BINDING
:
从组件中的elements
到相应组件的class
的信息流是事件绑定(HTML Template to TS)
。事件绑定的工作无需定义template reference variable.
,这是操作DOM元素的最佳和最简便的方法。 ()
表示event binding
。
下面是本示例的代码段:
HTML
<button (click)="changeColour()" [ngStyle]="{'background-color': buttonColor}">BUY NOW</button>
TS
buttonColor : string = 'grey'
changeColour() {
this.buttonColor = 'purple'
}
Angular还具有仅在particular event
上实现事件侦听器的功能,例如,在enter key is pressed
,mouse clicked
或combination of keys is pressed
上实现。
下面是本示例的代码段:
HTML
<button (keyup.control.shift.enter)="changeColour()" [ngStyle]="{'background-color': buttonColor}">BUY NOW</button>
当按下colour
时,按钮的purple
变成Ctrl+Shift+Enter
。
@HostListener and @HostBinding
:
这与event binding
和property binding
的角度相似。
@HostBinding('value') val;
与[value]="val"
和
@HostListener('click') click(){ }
与(click)="click()"
相同。
@HostBinding
和@HostListener
在directive
内部定义,而[]
和()
在component template
内部定义。
下面是本示例的代码段:
HTML
<button class="c_highlight">BUY NOW</button>
TS
(host.directive.ts)
@Directive({
// Notice the . in selector => this directive will work for DOM with the c_highlight class
selector: '.c_highlight'
})
export class HostDirective {
@HostBinding('style.backgroundColor') c_color = "red";
@HostListener('click') c_onclick() {
this.c_color = "purple" ;
}
}
Renderer2
:
这基本上是wrapper
上方的browser API for DOM Manipulation
。除了DOM之外,还可以运行across platforms
来运行Renderer2 API,并且可以提供平台独有的own Renderer2 implementation
。目前存在多种DOM操作methods
,例如setStyle()
,createElement()
,createText()
,appendChild()
等,我们可以实现自己的{{1} }方法。这与您的示例中的custom
类似,我们在元素template reference variable
的{{1}}中使用reference
。
下面是本示例的代码段:
HTML
modify
TS
properties
<button (click) = "onClick()" #abcd>BUY NOW</button>
:
这涉及为元素创建@ViewChild('abcd')
private abcd: ElementRef;
constructor(private renderer: Renderer2) {
}
onClick() {
this.renderer.setStyle(this.abcd.nativeElement, 'backgroundColor','purple');
}
。这类似于Template Reference Variable
方法,其中每个元素可以具有一个id (reference)
,并且可以使用jquery
方法在这些元素上定义事件。示例(如您的问题所示):
HTML
id
TS
getElementById()
<button (click)="changeColour()" id="buy-now">BUY NOW</button>
来自changeColour() {
const b = <HTMLElement>document.querySelector('#buy-now');
b.style.backgroundColour = 'purple'
}
:
这类似于在元素上定义fromEvent()
。 rxjs
方法创建一个Event Listener
,它发出来自给定元素的特定类型的事件。只需要声明元素的fromEvent
;该引用的事件为Observable
。示例:
HTML
reference
TS
associated
摘要:
用于<button #abcd>BUY NOW</button>
的技术的选择仅取决于@ViewChild('abcd')
private abcd: ElementRef;
ngOnInit(){
fromEvent(this.abcd.nativeElement, 'click').subscribe(res => this.abcd.nativeElement.style.backgroundColor = 'purple');
}
。这些方法中的每一个都有自己的DOM Manipulation
和developer
;就像事件绑定一样,benefits
可能在修改大型列表时相对较慢,因为trade-offs
仅在该函数返回后才能再次运行。方法1和2是performance
,因为这些元素change detection cycle
可能会带来风险,并且可能使您的应用程序受到{@Chellapan指出的best angular practices
更多avoid creating references
攻击。 / p>
答案 1 :(得分:2)
您可以使用template reference variable访问模板中的DOM元素:
<button #btn (click)="btn.style.backgroundColor = 'purple'">BUY NOW</button>
或者您可以将变量传递给方法:
<button #btn (click)="changeColor(btn)">BUY NOW</button>
并修改代码中的元素:
changeColour(element: HTMLElement) {
element.style.backgroundColour = 'purple';
}
有关演示,请参见this stackblitz。
答案 2 :(得分:2)
根据使用Element Ref的Angular文档可能容易受到攻击
允许直接访问DOM可以使您的应用程序更多 容易受到XSS攻击。仔细检查对ElementRef的任何使用 您的代码。有关更多详细信息,请参阅《安全指南》。
使用Renderer2来操作DOM。
在模板中创建一个模板引用,并将其传递给changeColour方法并使用renderer2服务,该服务提供setStyle方法来设置元素的样式
component.html
<button #button (click)="changeColour(button)">BUY NOW</button>
component.ts
constructor(private renderer: Renderer2) { }
changeColour(element: HTMLElement) {
this.renderer.setStyle(element.nativeElement, 'backgroundColour ', 'purple');
}