Html 如何在Angular2+中轻轻改变img src;
当我动态更改Html 如何在Angular2+中轻轻改变img src;,html,angular,Html,Angular,当我动态更改img的src属性时,加载新图像时会显示旧图像 我有一个显示一些数据的组件:文本和图像。单击后,基础数据发生更改(即来自服务器的新数据)。单击后,文本立即更改,但组件在加载新图像时显示旧图像。加载新图像后,它将以可视方式显示,这可能需要相当长的时间 在实际应用中,点击按钮可以获得产品详细信息和更改产品。立即替换所有数据,但不替换图像 组件未销毁(重用)时存在问题 我已经尝试过在单击后清除imagesrc,但它不起作用 我有一个简单的模板绑定 img [src]="img.url" s
img
的src
属性时,加载新图像时会显示旧图像
我有一个显示一些数据的组件:文本和图像。单击后,基础数据发生更改(即来自服务器的新数据)。单击后,文本立即更改,但组件在加载新图像时显示旧图像。加载新图像后,它将以可视方式显示,这可能需要相当长的时间
在实际应用中,点击按钮可以获得产品详细信息和更改产品。立即替换所有数据,但不替换图像
组件未销毁(重用)时存在问题
我已经尝试过在单击后清除imagesrc
,但它不起作用
我有一个简单的模板绑定
img [src]="img.url" style="width: 300px; height: 300px">
<p>{{ img.text }}</p>
你可以在这里看到示例应用程序
这是否可能对图像更改过程进行更多控制?例如,在单击时清除图像并等待背景为空的新图像将非常好。通过利用
img
和[ngStyle]
上的(加载)
事件,我终于达到了我想要的效果
在模板中,我添加了加载处理程序和样式:
<img [src]="img.url" style="width: 300px; height: 300px" (load)="loaded()"
[ngStyle]="{'display': imgVisible ? 'block' : 'none'}">
<img [src]="'https://loremflickr.com/300/300?random=' + index"
style="width: 300px; height: 300px" imgGhost>
在更改数据时,还可以隐藏图像:
this.imgVisible = false;
接下来,在加载图像时,显示图像(小心!当旧图像和新图像具有相同的URL时,不会引发此事件;如果是这种情况,则需要有条件地隐藏图像)
解决方案的完整代码:
我不太喜欢这种解决方案。当您有更多图像时,可能很难应用
欢迎使用所有更好的解决方案。我对stackblitz演示进行了一些修改,基本上我将您的代码包装在
ImageGhostDirective
中,以使其可重用。该指令使用MutationObserver
来更改样式,侦听src
属性上的任何更改。在“加载”事件上使用HostListener
,它会将样式恢复到正常状态。我从第一次加载时的不透明度0开始,然后在连续图像更改之间的不透明度为0.2,但这完全是任意的,可以用微调器或任何占位符替换
以下是stackblitz的链接:
还可以通过使用指令装饰器中的img:not([imgGhost])
选择器,告诉Angular自动将此指令附加到每个img
元素。这样,你就不必在应用程序中的每个图像上手动放置指令
希望这是有用的。如果你在CSS中使用背景+URL来处理图像,你可能可以通过使用过渡和硬编码背景颜色作为备用颜色来实现你想要的效果。效果很好。以前没有听说过MutationObserver WebAPI。谢谢你教新东西:)@jo_va,优雅的解决方案:)
this.imgVisible = false;
loaded(): void {
this.imgVisible = true;
}
<img [src]="'https://loremflickr.com/300/300?random=' + index"
style="width: 300px; height: 300px" imgGhost>
@Directive({
selector: 'img[imgGhost]'
})
export class ImageGhostDirective implements OnDestroy {
private changes: MutationObserver;
constructor(private elementRef: ElementRef) {
this.changes = new MutationObserver((mutations: MutationRecord[]) =>
mutations.filter(m => m.attributeName === 'src').forEach(() => this.opacity = 0.2)
);
this.changes.observe(this.elementRef.nativeElement, {
attributes: true,
childList: false,
characterData: false
});
}
ngOnDestroy(): void {
this.changes.disconnect();
}
@HostBinding('style.display') display = 'block';
@HostBinding('style.opacity') opacity = 0;
@HostListener('load')
onLoad(): void {
this.opacity = 1;
}
}