我们在Angular 9应用中大量使用了HTML5的picture
标签。当实际的src返回404时,我们现在想要显示一个回退图像。
我创建了一个指令来代替img src,就像这个答案所建议的那样:
@Directive({
selector: '[fallbackSrc]',
})
export class FallbackImageDirective {
constructor(
@Attribute('fallbackSrc') public fallbackSrc: string,
private renderer: Renderer2,
private el: ElementRef
) {}
@HostListener('error') onError() {
this.renderer.setAttribute(this.el.nativeElement, 'src', this.fallbackSrc);
}
}
在图片标签中工作:
<picture>
<source
*ngIf="_teaser.images.i377_212_webp"
[srcset]="_teaser.images.i377_212_webp"
type="image/webp"
/>
<img
loading="lazy"
[alt]="_teaser.image_alt"
[src]="_teaser.images.i377_212"
fallbackSrc="/ng-assets/images/backgrounds/teaser_fallback_image.png"
class="preview-image"
/>
</picture>
但是,当我打开应用程序时,对wepP-Image的请求会不断地. 我怀疑浏览器注意到<img src=
的变化并再次开始评估<source>
标签,然后失败,再次调用onError()
,导致无限循环.
我也尝试过这个解决方案,但它什么也没做(可能是因为它是针对旧版本的Angular)。
我能做些什么来阻止浏览器再次评估source
标签吗?
我通过删除onError
方法内的source
标签使其工作:
@HostListener('error') onError() {
const parentNode = this.el.nativeElement.parentNode;
if (parentNode.tagName.toLowerCase() === 'picture') {
for (let child of parentNode.children) {
if (child.tagName.toLowerCase() === 'source') {
parentNode.removeChild(child);
}
}
}
this.renderer.setAttribute(this.el.nativeElement, 'src', this.fallbackSrc);
}