Last active
October 26, 2023 12:48
-
-
Save jkyoutsey/74ee55ecea86fe16ca8b79f99b5a33d5 to your computer and use it in GitHub Desktop.
Angular Dynamic Script Execution Directive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div appDynamicScript> | |
<!-- most tags work, but Angular strips script tags, so don't try it. --> | |
<div | |
src="http://some.script.com/thing.js" | |
my-custom-attr="some value" | |
> | |
Some Text | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { DOCUMENT } from '@angular/common'; | |
import { Directive, ElementRef, Inject, AfterViewInit } from '@angular/core'; | |
@Directive({ | |
selector: '[appDynamicScript]', | |
}) | |
export class DynamicScriptDirective implements AfterViewInit { | |
constructor(private el: ElementRef, @Inject(DOCUMENT) private document: Document) {} | |
ngAfterViewInit() { | |
const templateEl = this.el.nativeElement.firstElementChild as HTMLElement; | |
if (templateEl) { | |
this.replaceDivWithScript(templateEl); | |
} | |
} | |
private replaceDivWithScript(templateEl: HTMLElement) { | |
const script = this.document.createElement('script'); | |
this.copyAttributesFromTemplateToScript(templateEl, script); | |
this.copyTemplateContentToScript(templateEl, script); | |
templateEl.remove(); | |
// add the new script element to the host div so the browser will execute it | |
this.el.nativeElement.appendChild(script); | |
} | |
private copyAttributesFromTemplateToScript(templateEl: HTMLElement, script: HTMLScriptElement) { | |
for (let a = 0; a < templateEl.attributes.length; a++) { | |
script.attributes.setNamedItem(templateEl.attributes[a].cloneNode() as Attr); | |
} | |
} | |
private copyTemplateContentToScript(templateEl: HTMLElement, script: HTMLScriptElement) { | |
const scriptContent = this.document.createTextNode(templateEl.textContent); | |
script.appendChild(scriptContent); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment