Last active
February 24, 2018 14:49
-
-
Save havran/7b28b7e3f1527f562eadf422081051f3 to your computer and use it in GitHub Desktop.
Angular 2+ directive for routing HTML links in raw loaded HTML
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 {Directive, ElementRef, Inject, HostListener} from '@angular/core'; | |
import {Router} from '@angular/router'; | |
import {DOCUMENT} from '@angular/common'; | |
@Directive({ | |
selector: '[linksInHtml]' | |
}) | |
export class LinksInHtmlDirective { | |
constructor(private el: ElementRef, private router: Router, @Inject(DOCUMENT) private documentRef: any) { } | |
@HostListener('click', ['$event', '$event.target']) | |
onClick(event: Event, eventTarget: HTMLElement) { | |
// We need get clicked anchor but sometimes is other HTML element in anchor. | |
const anchorElement: HTMLAnchorElement | boolean = this.getClickedAnchor(new ElementRef(eventTarget)); | |
if (anchorElement === false) { | |
return; | |
} | |
// You can use attributes href (full URL), protocol, hostname, port, pathname, search, hash, origin (protocol + hostname + port). | |
// For accessing to URL parts use - this.window.location | |
// - el ('a' element) | |
// | |
// If link is local we can navigate through Angular Router. | |
if (anchorElement.hostname === this.documentRef.location.hostname && anchorElement.port === this.documentRef.location.port) { | |
// Stop event bubling. | |
event.preventDefault(); | |
event.stopPropagation(); | |
// Navigate. | |
this.router.navigateByUrl(anchorElement.pathname + anchorElement.search + anchorElement.hash); | |
} | |
// All other links. | |
else { | |
// Set target blank for other links. | |
if (!anchorElement.getAttribute('target')) { | |
anchorElement.setAttribute('target', '_blank'); | |
anchorElement.dispatchEvent(event); | |
} | |
} | |
} | |
getClickedAnchor(node: ElementRef) { | |
while (this.elementIsNotComponentElement(node) && this.elementIsNotAnchor(node)) { | |
node = new ElementRef(node.nativeElement.parentNode); | |
} | |
if (this.elementIsAnchor(node)) { | |
return node.nativeElement as HTMLAnchorElement; | |
} | |
return false; | |
} | |
private elementIsNotComponentElement(el: ElementRef) { | |
return el.nativeElement !== this.el.nativeElement; | |
} | |
private elementIsNotAnchor(el: ElementRef) { | |
return el.nativeElement.tagName.toLowerCase() !== 'a'; | |
} | |
private elementIsAnchor(el: ElementRef) { | |
return !this.elementIsNotAnchor(el); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment