我有一个使用Angular并从TS文件路由数据的网页。一切正常,除了(单击)。
如果我将带有(click)函数的SVG直接放在HTML中,则可以使用,但是,如果我从TS文件中调用SVG,则不可以。如果删除(click)= linkOpen(),则该链接会继续在新窗口中打开;如果我删除target = iframe,则该链接会在当前标签中打开。
project.component.html:
<div class="page" *ngIf="project$ | async as project">
<div [innerHTML]="svgHTML(project)"></div>
</div>
project.component.ts:
import { Component, OnInit, Injectable } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { switchMap } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { DomSanitizer } from '@angular/platform-browser';
import { CopeAdditionsService } from '../cope-additions.service';
import { Project } from '../project';
@Component({
selector: 'app-project',
templateUrl: './project.component.html',
styleUrls: ['./project.component.css']
})
@Injectable()
export class ProjectComponent implements OnInit {
display: boolean;
project$: Observable<Project>;
constructor(
private route: ActivatedRoute,
private router: Router,
private service: CopeAdditionsService,
public sanitizer: DomSanitizer
) {
this.display = false;
}
ngOnInit() {
this.project$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) =>
this.service.getProject(params.get('id')))
);
}
gotoProjects(project: Project) {
let projectId = project ? project.id : null;
this.router.navigate(['/cope-additions', { id: projectId }]);
}
linkOpen() {
if (window.innerWidth >= 600) {
this.display = true;
document.getElementById('imgLink').setAttribute('target', 'iframe');
} else {
this.display = false;
document.getElementById('imgLink').setAttribute('target', '_self');
}
}
svgHTML(project) {
return this. sanitizer.bypassSecurityTrustHtml(project.SVG);
}
}
project-details.ts:
SVG:`
<svg class=\'svg\' fill=\'transparent\' id=\'svg5\' xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 476 612\'>
<a href=\'/cope-additions/5/lot/15\' id=\'imgLink\' target=\'iframe\' (click)=\'linkOpen()\'><rect class=\'lot-for-sale\' x=\'64\' y=\'40\' width=\'125.5\' height=\'95\' alt=\'B-1\'><title>lot for sale</title></rect></a>
</svg>`
该链接不是在iframe中打开,而是在一个新标签页中打开,但在移动设备上则完全不会打开。在将SVG移到TS文件(直接在HTML文件中)之前,该链接也没有在移动设备上打开,尽管在使用Chrome检查器作为设备进行预览时linkOpen()可以按预期工作/工作。>
答案 0 :(得分:2)
我对问题的理解是,您需要为#imgLink添加一个click的事件监听器。但是,直到它存在,您才能做到这一点,您需要将元素包含在DOM中以添加事件。 Afaik,(点击)方法由于Sam所说的原因而行不通。
https://stackblitz.com/edit/angular-bhbwkd
从概念上显示了如何执行此操作。问题在于它涉及内部setTimeout,而且还不够漂亮。所以问题基本上只是时间。
一种方法是使用指令,在ngAfterViewInit(https://angular.io/guide/lifecycle-hooks)中设置click事件。它可能还需要一个输出(https://angular.io/guide/component-interaction#parent-listens-for-child-event)。另一种选择是使用完整组件,其模板是project-details.ts中的svg。然后,您可以“正常”捕获点击事件。
其他一些建议:
为什么它可能不适用于移动设备:谁知道移动设备很奇怪(这是因为他的专职工作是为带角度的移动设备开发的人)。但是,严重的是,有些链接可能对https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Supporting_both_TouchEvent_and_MouseEvent,https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Using_Touch_Events有帮助。通常,如果您获得触摸事件,那么您也应该获得点击事件。 SVG可能是魔术。我建议尝试捕获所有的触摸/单击事件,以查看正在运行的事件及其顺序,然后尝试找出原因。如果您打算做任何复杂的事情,而需要良好的移动支持http://hammerjs.github.io/就是一个很好的解决方案。
尾注:如果手动添加点击事件,则我建议使用Renderer2而不是直接进行操作https://medium.com/@kmathy/angular-manipulate-properly-the-dom-with-renderer-16a756508cba,这比我可以解释的更好。
答案 1 :(得分:1)
答案 2 :(得分:0)
把click事件放在调用innerHTML的div上,并将目标留在SVG上的一个元素上就可以了,不需要任何侦听器。
为解决移动问题,我复制了SVG,使用打字稿仅在移动设备上调用它,并在href中添加了“ xlink:”,因为iOS要求这么做。 Xlink已废弃,但似乎没有其他作用。