在将 MutationObserver 添加到我的应用程序时,我遇到了一个非常奇怪的错误。 我的一个 Angular 组件正在使用 HostBinding 到元素的 attr.style 属性,直到几天前我设置属性标志时,这与我注入到页面(从另一个 js 文件)的突变观察器一起工作得很好对于突变观察者来说为 true,然后选项卡完全崩溃并陷入循环。 我不知道为什么,突变观察者不应该引起或触发任何新事件,它应该只观察,所以我不明白监听页面中元素的属性会如何导致它,除非它做了更多的事情而不是只是听?
我设置了一个快速演示,有2个HostBindings,第一个与问题无关,主要问题是与attr.style的绑定。 如果您想重新创建错误,请将观察者的属性标志设置为 true。
如有任何帮助,我们将不胜感激,谢谢!
我尝试将属性标志设置为 false,它确实有帮助,我只是不明白为什么。我需要继续使用该标志。另一种选择是删除该绑定并稍后手动设置该 css 规则。
@Component({
selector: 'hello',
template: `<h1 >This is a {{name}}!!!</h1>
<button (click)='activate()'>Activate</button>`,
styles: [
`
h1 { font-family: montserrat;}`,
],
})
export class HelloComponent implements OnInit {
@Input() name: string;
toggle: boolean;
toogle: boolean;
@HostBinding('class.Current')
get t() {
console.log('getter-toggle function called');
return this.toggle;
}
@HostBinding('attr.style')
public get cssVariables() {
console.log('getter-cssRules function called');
const cssVariables = `
--sq-color: blue
`;
return this.sanitizer.bypassSecurityTrustStyle(cssVariables);
}
constructor(private sanitizer: DomSanitizer) {}
activate() {
this.toggle = !this.toggle;
console.log(this.toggle);
}
ngOnInit() {
let observer = new MutationObserver(this.logChanges);
observer.observe(window.document.documentElement, {
childList: true,
subtree: true,
attributes: false, // Switch this to true if you want to crash the tab
});
}
logChanges(records, observer) {
for (const record of records) {
console.log(record);
}
}
}
首先,这很奇怪,您从一个组件创建一个突变观察器,用于监视包含组件中的更改的文档更改。但也许这只是一个示例代码。
每次调用 getter 时,
@HostBinding('attr.style')
都会设置新值,因为清理会创建一个与之前调用该函数不同的对象。因此,每次渲染都会返回不同的值。
MutationObserver 侦听器中的某些内容使侦听器导致组件重新渲染。这会更改样式属性并导致 MutationObserver 侦听器再次被调用。我尝试在角度区域之外运行侦听器,但这没有帮助。
有帮助的是仅清理一次样式值:
@HostBinding('attr.style')
public get cssVariables() {
console.log('getter-cssRules function called');
return this.sanitizedValue
}
private sanitizedValue = null
constructor(private sanitizer: DomSanitizer) {
this.sanitizedValue = this.sanitizer.bypassSecurityTrustStyle(`
--sq-color: blue
`);
}
这样即使在观察属性变化时它也能工作。