Created
April 6, 2018 15:15
-
-
Save Dok11/d8023196a237a34836afbe52f216592a to your computer and use it in GitHub Desktop.
Angular 5. Href links inside SPA
This file contains hidden or 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
export class AppComponent { | |
@HostListener('click', [ | |
'$event.target', | |
'$event.button', | |
'$event.ctrlKey', | |
'$event.metaKey', | |
]) | |
private onClick( | |
eventTarget: HTMLElement, | |
button: number, | |
ctrlKey: boolean, | |
metaKey: boolean, | |
): boolean { | |
// Deal with anchor clicks; climb DOM tree until anchor found (or null) | |
let target = eventTarget; | |
while (target && !(target instanceof HTMLAnchorElement)) { | |
target = target.parentElement; | |
} | |
if (target instanceof HTMLAnchorElement) { | |
return this.handleAnchorClick(target, button, ctrlKey, metaKey); | |
} | |
// Allow the click to pass through | |
return true; | |
} | |
/** | |
* Handle user's anchor click | |
* | |
* @param anchor {HTMLAnchorElement} - the anchor element clicked | |
* @param button Number of the mouse button held down. 0 means left or none | |
* @param ctrlKey True if control key held down | |
* @param metaKey True if command or window key held down | |
* @return false if service navigated with `go()`; true if browser should | |
* handle it. | |
*/ | |
private handleAnchorClick( | |
anchor: HTMLAnchorElement, | |
button = 0, | |
ctrlKey = false, | |
metaKey = false, | |
) { | |
// Check for modifier keys and non-left-button, which indicate the user wants to control | |
// navigation | |
if (button !== 0 || ctrlKey || metaKey) { | |
return true; | |
} | |
// If there is a target and it is not `_self` then we take this | |
// as a signal that it doesn't want to be intercepted. | |
// TODO: should we also allow an explicit `_self` target to opt-out? | |
const anchorTarget = anchor.target; | |
if (anchorTarget && anchorTarget !== '_self') { | |
return true; | |
} | |
if (anchor.getAttribute('download')) { | |
return true; // let the download happen | |
} | |
const { pathname, search, hash } = anchor; | |
const relativeUrl = pathname + search + hash; | |
// don't navigate if external link or has extension | |
if ( anchor.getAttribute('href') !== relativeUrl || | |
!/\/[^/.]*$/.test(pathname) ) { | |
return true; | |
} | |
// parse url for get query parameters | |
const tree: UrlTree = this.router.parseUrl(relativeUrl); | |
let cleanUrl: string = relativeUrl.replace(/\?.*/, ''); | |
// remove fragment from cleanUrl | |
if (tree.fragment) { | |
cleanUrl = cleanUrl.replace(`#${tree.fragment}`, ''); | |
} | |
// approved for navigation | |
this.router.navigate([cleanUrl], { | |
queryParams: tree.queryParams, | |
fragment: tree.fragment, | |
}); | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment