Angular 指令:悬停时动态更改图像背景
Angular directive: Dynamic change img background on hover
查看屏幕截图,我有页面的背景图片和文本下方的两个缩略图。我希望能够在鼠标悬停缩略图时将页面的 background
图像更改为缩略图的图像。
以下是我的指令。我可以获得缩略图的 src
但我不知道如何将其注入元素以便页面背景发生变化。此外,我已经从 ViewChild
行收到错误 Expected 2 arguments, but got 1.
。
import { Directive, ElementRef, HostListener, ViewChild } from '@angular/core';
@Directive({
selector: '[dynamicBackgroundImg]'
})
export class DynamicBackgroundImgDirective {
thumbSRC : string;
@ViewChild('tourBackgroundImg') tourBackgroundImg:ElementRef;
constructor(private el: ElementRef) {}
@HostListener('mouseover') onMouseOver() {
this.ChangeBackgroundImg();
}
@HostListener('mouseleave') onMouseLeave() {
}
ChangeBackgroundImg() {
this.thumbSRC = this.el.nativeElement.getAttribute('src');
alert(this.thumbSRC);
this.tourBackgroundImg.nativeElement.setAttribute(this.thumbImgSrc);
}
}
这是我的 HTML 的缩小版本:
<section class="tours-section" [ngClass]="{ 'load-complete' : viewPage }">
<img class="component-loader" src="../../../assets/icons/loading.svg">
<div class="tours-wrapper">
<div class="tours-right page-title">
<p>{{pageTitle}}</p>
<picture>
<source srcset="{{ toursImageUrl }}?fm=webp" type="image/webp">
<source srcset="{{ toursImageUrl }}?fm=png" type="image/png">
<!-- Here is the tag that sets the background img of the page, when one hover over the thumnail, this needs to change, the src of the thumb needs to be injected here. -->
<img src="{{ toursImageUrl }}?fm=png" alt="{{ toursImageAlt }}" (load)="imageLoaded()" class="section-background" tourBackgroundImg>
</picture>
</div>
<div class="tours-left">
<div class="tours-thumbs">
<div class="tours-container">
<!-- Ideally when one hovers over the thumnail, it would get the src of the tour-image -->
<figure class="tour-image-small">
<picture>
<img src="assets/images/L1000433-min.JPG" alt="" dynamicBackgroundImg>
<figcaption></figcaption>
</picture>
</figure>
</div>
</div>
</div>
</div>
</div>
</section>
下面是一张截图,希望能帮助您理解我想要实现的目标:
很可能我对整件事的理解是错误的,欢迎任何意见。
您可以在图像上使用事件侦听器来执行此操作:Repro on Stackblitz
代码如下:
html:
<div class="app-component">
<h1>App Component</h1>
hover this image to change the background:<br>
<img #myImage src="https://picsum.photos/200/300"/>
</div>
css(只需设置图像即可更改):
.app-component{
background-image: url("https://img.maxisciences.com/s3/frgsd/1024/coronavirus/default_2020-02-28_2bbef01b-f63a-4a59-b31e-788da4e402bb.jpeg");
}
和 TS :
import {
Component,
OnInit,
ElementRef,
ViewChild,
Renderer2,
AfterViewInit
} from "@angular/core";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements AfterViewInit {
@ViewChild("myImage") myImage: ElementRef;
globalInstance: any;
constructor(private renderer: Renderer2) {}
ngAfterViewInit() {
this.globalInstance = this.renderer.listen(
this.myImage.nativeElement,
"mouseover",
() => {
this.renderer.setStyle(
document.body.querySelector('.app-component'),
"background-image",
`url(${this.myImage.nativeElement.src})`
);
}
);
}
}
如您所见,我们的想法是绑定并监听图像上的事件(此处为 'mouseover' 事件)并在触发时更改目标的背景(此处为 appComponent)。
您的指令中无需使用 @ViewChild
。
以下代码应该有效:
import { Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core';
@Directive({
selector: '[dynamicBackgroundImg]'
})
export class DynamicBackgroundImgDirective {
// use the @Input to pass the target image
@Input() target: HTMLImageElement;
constructor(private el: ElementRef<HTMLImageElement>, private renderer: Renderer2) {}
@HostListener('mouseover') onMouseOver() {
this.ChangeBackgroundImg();
}
@HostListener('mouseleave') onMouseLeave() {
}
ChangeBackgroundImg() {
// use the Renderer2 service to set the attribute
this.renderer.setAttribute(this.target, 'src', this.el.nativeElement.src);
// Add fade-in css class
this.renderer.addClass(this.target, 'fade-in');
}
}
在组件模板中:
<- add a template variable for the image that you want to display it ->
<img src="{{ toursImageUrl }}?fm=png" alt="{{ toursImageAlt }}" (load)="imageLoaded()" class="section-background" #tourBackgroundImg>
....
<- When you hover this image the tourBackgroundImage will change the source ->
<img src="assets/images/L1000433-min.JPG" dynamicBackgroundImg [target]="tourBackgroundImg">
ViewChild 行中的错误 Expected 2 arguments, but got 1
让我相信您正在使用 Angular 8。如果是这样,您需要在 @ViewChild
中传递一个配置对象,如下所示:
@ViewChild('element', { static: false })
如果在OnInit
生命周期钩子中使用,static
属性必须是true
,否则false
。在以前的版本以及 Angular 9 中,第二个参数是可选的,除非它不在 ngOnInit
.
中使用
更新-动画
要使图像动起来,您可以使用 Angular 动画或简单的 css,如下所示:
.fade-in {
animation: fadeIn ease 1s;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
我在指令中添加了用于在悬停缩略图时添加 fade-in
class 的代码。
查看屏幕截图,我有页面的背景图片和文本下方的两个缩略图。我希望能够在鼠标悬停缩略图时将页面的 background
图像更改为缩略图的图像。
以下是我的指令。我可以获得缩略图的 src
但我不知道如何将其注入元素以便页面背景发生变化。此外,我已经从 ViewChild
行收到错误 Expected 2 arguments, but got 1.
。
import { Directive, ElementRef, HostListener, ViewChild } from '@angular/core';
@Directive({
selector: '[dynamicBackgroundImg]'
})
export class DynamicBackgroundImgDirective {
thumbSRC : string;
@ViewChild('tourBackgroundImg') tourBackgroundImg:ElementRef;
constructor(private el: ElementRef) {}
@HostListener('mouseover') onMouseOver() {
this.ChangeBackgroundImg();
}
@HostListener('mouseleave') onMouseLeave() {
}
ChangeBackgroundImg() {
this.thumbSRC = this.el.nativeElement.getAttribute('src');
alert(this.thumbSRC);
this.tourBackgroundImg.nativeElement.setAttribute(this.thumbImgSrc);
}
}
这是我的 HTML 的缩小版本:
<section class="tours-section" [ngClass]="{ 'load-complete' : viewPage }">
<img class="component-loader" src="../../../assets/icons/loading.svg">
<div class="tours-wrapper">
<div class="tours-right page-title">
<p>{{pageTitle}}</p>
<picture>
<source srcset="{{ toursImageUrl }}?fm=webp" type="image/webp">
<source srcset="{{ toursImageUrl }}?fm=png" type="image/png">
<!-- Here is the tag that sets the background img of the page, when one hover over the thumnail, this needs to change, the src of the thumb needs to be injected here. -->
<img src="{{ toursImageUrl }}?fm=png" alt="{{ toursImageAlt }}" (load)="imageLoaded()" class="section-background" tourBackgroundImg>
</picture>
</div>
<div class="tours-left">
<div class="tours-thumbs">
<div class="tours-container">
<!-- Ideally when one hovers over the thumnail, it would get the src of the tour-image -->
<figure class="tour-image-small">
<picture>
<img src="assets/images/L1000433-min.JPG" alt="" dynamicBackgroundImg>
<figcaption></figcaption>
</picture>
</figure>
</div>
</div>
</div>
</div>
</div>
</section>
下面是一张截图,希望能帮助您理解我想要实现的目标:
很可能我对整件事的理解是错误的,欢迎任何意见。
您可以在图像上使用事件侦听器来执行此操作:Repro on Stackblitz
代码如下:
html:
<div class="app-component">
<h1>App Component</h1>
hover this image to change the background:<br>
<img #myImage src="https://picsum.photos/200/300"/>
</div>
css(只需设置图像即可更改):
.app-component{
background-image: url("https://img.maxisciences.com/s3/frgsd/1024/coronavirus/default_2020-02-28_2bbef01b-f63a-4a59-b31e-788da4e402bb.jpeg");
}
和 TS :
import {
Component,
OnInit,
ElementRef,
ViewChild,
Renderer2,
AfterViewInit
} from "@angular/core";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements AfterViewInit {
@ViewChild("myImage") myImage: ElementRef;
globalInstance: any;
constructor(private renderer: Renderer2) {}
ngAfterViewInit() {
this.globalInstance = this.renderer.listen(
this.myImage.nativeElement,
"mouseover",
() => {
this.renderer.setStyle(
document.body.querySelector('.app-component'),
"background-image",
`url(${this.myImage.nativeElement.src})`
);
}
);
}
}
如您所见,我们的想法是绑定并监听图像上的事件(此处为 'mouseover' 事件)并在触发时更改目标的背景(此处为 appComponent)。
您的指令中无需使用 @ViewChild
。
以下代码应该有效:
import { Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core';
@Directive({
selector: '[dynamicBackgroundImg]'
})
export class DynamicBackgroundImgDirective {
// use the @Input to pass the target image
@Input() target: HTMLImageElement;
constructor(private el: ElementRef<HTMLImageElement>, private renderer: Renderer2) {}
@HostListener('mouseover') onMouseOver() {
this.ChangeBackgroundImg();
}
@HostListener('mouseleave') onMouseLeave() {
}
ChangeBackgroundImg() {
// use the Renderer2 service to set the attribute
this.renderer.setAttribute(this.target, 'src', this.el.nativeElement.src);
// Add fade-in css class
this.renderer.addClass(this.target, 'fade-in');
}
}
在组件模板中:
<- add a template variable for the image that you want to display it ->
<img src="{{ toursImageUrl }}?fm=png" alt="{{ toursImageAlt }}" (load)="imageLoaded()" class="section-background" #tourBackgroundImg>
....
<- When you hover this image the tourBackgroundImage will change the source ->
<img src="assets/images/L1000433-min.JPG" dynamicBackgroundImg [target]="tourBackgroundImg">
ViewChild 行中的错误 Expected 2 arguments, but got 1
让我相信您正在使用 Angular 8。如果是这样,您需要在 @ViewChild
中传递一个配置对象,如下所示:
@ViewChild('element', { static: false })
如果在OnInit
生命周期钩子中使用,static
属性必须是true
,否则false
。在以前的版本以及 Angular 9 中,第二个参数是可选的,除非它不在 ngOnInit
.
更新-动画
要使图像动起来,您可以使用 Angular 动画或简单的 css,如下所示:
.fade-in {
animation: fadeIn ease 1s;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
我在指令中添加了用于在悬停缩略图时添加 fade-in
class 的代码。