Angular2 Directive: How to detect DOM changes
Asked Answered
F

1

22

I want to implement Skrollr as an Angular2 attribute directive.

So, the format may be:

<body my-skrollr>
</body>

However, in order to implement this, I need to be able to detect changes in the DOM in child elements below the containing tag (in this case, <body>), so that I can call skrollr.init().refresh(); and update the library to work with the new content.

Is there a straightforward way of doing this that I'm not aware of, or am I approaching this incorrectly?

Fervor answered 21/3, 2016 at 11:56 Comment(0)
P
36

Angular does not provide something built-in for that purpose. You can use MutationObserver to detect DOM changes.

@Directive({
  selector: '[my-skrollr]',
  ...
})
class MyComponent {
  constructor(private elRef:ElementRef) {}

  ngAfterViewInit() {
    this.observer = new MutationObserver(mutations => {
      mutations.forEach(function(mutation) {
        console.log(mutation.type);
      });   
    });
    var config = { attributes: true, childList: true, characterData: true };

    this.observer.observe(this.elRef.nativeElement, config);
  }
}
Putrescent answered 21/3, 2016 at 12:1 Comment(7)
In MutationObserver constructor it should be "mutations" instead of "mutation"Ulterior
thank you for this... Can someone tell me wha th opposite of what this would be... i.e. detecting nothing changed? if that makes sense. lol I need something to turn off the variable.Met
Perhaps you can check that no mutation event was emitted for a specific amount of time?Agamic
@ChristianMatthew - Surely you would simply set a state to "false" and then just change to true when something changes?Fervor
Don't forget to call this.observer.disconnect(); inside the ngOnDestroy() methodDisease
Is it safe to use ElementRef.nativeElement? I thought that posed XSS risk for the application.Whiskey
Using nativeElement is not related to XSS as long as you do not use it to append user-generated content (directly or indirectly) to the DOM. Access to nativeElement was frowned upon at the beginning of Angular 2 development because it would be incompatible with server-side rendering and web-worker but they are not used widely anyway and only the few that do need to take care. The current status is as far as I remember, that passing around nativeElement is now compatible with SSR/WW, but accessing methods or properties is not.Agamic

© 2022 - 2024 — McMap. All rights reserved.