Skip to content

Instantly share code, notes, and snippets.

@Dok11
Last active March 10, 2019 03:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dok11/4c04d29c6b9e5106b8731bb44eb53dfa to your computer and use it in GitHub Desktop.
Save Dok11/4c04d29c6b9e5106b8731bb44eb53dfa to your computer and use it in GitHub Desktop.
Angular native href work as routerLink
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