Я связываюсь с бэкендом, который возвращает полный файл .html, который должен отображаться в компоненте Angular. Когда я получаю файл, у него есть переходы к якорям, которые не работают в Angular7, так как он пытается перейти к localhost: 4200 / #. Я хочу позволить пользователям использовать якоря для навигации.
Я пытался сделать это без использования каких-либо пакетов, использования InnerHtml, OuterHtml, ElementRef, ViewContainerRef и анализа данных в Backend.
Я попытался заменить:
href = "# id" с href = "javascript :; (click) =" navigate (#id) "и routerLink с фрагментацией.
Проблема в том, что этот недавно внедренный код не работает из-за DOM Sanitazation.
@ViewChild('dynamic', { read: ElementRef }) dynamic: ElementRef;
private loadHtmlData(data: string) {
// Only take body
data = data.split("<body")[1].split(">").slice(1).join(">").split("</body>")[0];
let pageRegex = /(href="#page-)/g;
data = data.replace(pageRegex, 'href="javascript:;" [routerLink]="[]" fragment="page-');
this.fullHtml = data;
this.dynamic.nativeElement.outerHTML = data;
this.htmlLoaded = true;
}
<!-- Direct Injection
<div [innerHTML]="fullHtml | sanitizeHtml"
*ngIf="htmlLoaded"></div>
-->
<div #dynamic>
</div>
Ожидалось, что нажатие на вновь отформатированную ссылку приведет меня к этому якору.
Исправлено так:
<div [innerHTML]="navigationHtml | sanitizeHtml: 'html'"
(click)="loadedHtmlClicked($event)"
*ngIf="htmlLoaded">
</div>
loadedHtmlClicked(event) {
if (event && event.target && event.target.attributes) {
let attributes: NamedNodeMap = event.target.attributes;
let fragment = attributes.getNamedItem('fragment');
if (fragment && this.fragment != fragment.value) {
this.router.navigate([], { fragment: fragment.value });
let element = document.getElementById(fragment.value);
if (element) {
// Allows for some padding above element
window.scrollTo({
top: element.offsetTop + 60,
behavior: "smooth"
});
}
}
}
}