I get HTML as string as API response. The HTML contains few internal script tags which has functions called under $(window).load(). How do I load this HTML in my angular app.
I tried appending HTML string response to iFrame body. The HTML loads but the script tags aren't executed as window.load event is not fired when the angular route changes.
How do I approach this problem. Here's my code:
component.ts
ngOnInit() {
const html = "
<html>
<body>
<h1>Hello world</h1>
<script>
$(window).on('load', function() {
console.log('I am in the function')
})
</script>
</body>
</html>"
this.iframeDoc = this.iframe.nativeElement.contentDocument
this.iframeDoc.body.innerHTML = html;
}
component.html
<iframe #iframe></iframe>
I want "I am in the function" to be logged when the iframe content is appended.
EDIT:
I also tried appending the HTML to a div instead of an iFrame. Here's the code:
component.html
<div id="wrapper" appRunScripts></div>
component.ts
ngOnInit() {
const html = "
<html>
<body>
<h1>Hello world</h1>
<script>
$(window).on('load', function() {
console.log('I am in the function')
})
</script>
</body>
</html>"
const wrapper = document.getElementById('wrapper');
wrapper.innerHTML = html;
}
Also added a directive to run scripts within HTML. Here's the drective run-scripts.directive.ts
import { Directive, ElementRef, OnInit } from '@angular/core';
@Directive({
selector: '[appRunScripts]'
})
export class RunScriptsDirective implements OnInit {
constructor(private elementRef: ElementRef) { }
ngOnInit(): void {
setTimeout(() => { // wait for DOM rendering
this.reinsertScripts();
});
}
reinsertScripts(): void {
const scripts = <HTMLScriptElement[]>this.elementRef.nativeElement.getElementsByTagName('script');
const scriptsInitialLength = scripts.length;
for (let i = 0; i < scriptsInitialLength; i++) {
const script = scripts[i];
const scriptCopy = <HTMLScriptElement>document.createElement('script');
scriptCopy.type = script.type ? script.type : 'text/javascript';
if (script.innerHTML) {
scriptCopy.innerHTML = script.innerHTML;
} else if (script.src) {
scriptCopy.src = script.src;
}
scriptCopy.async = false;
script.parentNode.replaceChild(scriptCopy, script);
}
}
}