angular下实现轮播图不需要像jq那样操作dom,本人将轮播图封装成了一个组件,实现的效果图如下
代码如下
1.html文件
<ul [@carousel] = 'state'>
<li class='imgP' [ngClass]="{'activeLi': img.state===true}" *ngFor='let img of images,let i =index;' (mouseleave)='start()' (touchstart)="getStartX($event)" (touchend)="getEndX(i)" (touchmove)="getMoveX($event)">
<img [src]="url+img.name" *ngIf='img.state'>
</li>
</ul>
<div class='dot' fxLayout="row" fxLayoutAlign="center end" fxLayoutGap="15px">
<div class='circle' [class.active]='img.state' *ngFor='let img of images' (mouseenter)="clickDot(img.id)" (mouseleave)='blurDot()'>
</div>
</div>
</div>
#### 2.ts文件
import { Component, OnInit, OnDestroy} from '@angular/core';
import {trigger, style, transition, query, animate, group} from '@angular/animations';
@Component({
selector: 'app-carousel',
templateUrl: './carousel.component.html',
styleUrls: ['./carousel.component.scss'],
animations: [
trigger('carousel', [
transition(':increment', [
group([
query(':enter', [
style({transform: 'translateX(-100%)'}),
animate('1s')
]),
query(':leave',[
animate('1s', style({transform: 'translateX(100%)'}))
])
])
]),
transition(':decrement', [
group([
query(':enter', [
style({transform: 'translateX(100%)'}),
animate('1s')
]),
query(':leave', [
animate('1s', style({transform: 'translateX(-100%)'}))
])
])
]),
])
]
})
export class CarouselComponent implements OnInit, OnDestroy {
url = '/assets/images/'; //图片文件路径
state = 0;
timer: any; //定时器
imgIndex = 2;
startX: any; //起始触摸位置
endX: any; //离开触摸位置
startTime: number; //其实触摸时间
endTime: number; //结束触摸时间
screenWidth = document.documentElement.offsetWidth;
images = [
{id: 1, name: 'marketBg1.jpg', state: true},
{id: 2, name: 'marketBg2.jpg', state: false},
{id: 3, name: 'marketBg3.jpg', state: false},
{id: 4, name: 'marketBg4.jpg', state: false},
];
constructor() { }
//组件初始化后立即调用轮播方法fn()
ngOnInit() {
this. timer = setInterval(() => this.fn(), 5000);
}
ngOnDestroy() {
// 停止轮播
this.stop();
//清空定时器
clearInterval(this. timer);
}
fn() {
this. imgIndex++;
//轮播到最后一张图片时将图片索引置为零
if (this.imgIndex> this.images.length - 1) {
this.imgIndex = 0;
}
this.images.forEach(val => {
val.state = false;
});
this.images[this.imgIndex].state = true;
}
//结束轮播
stop() {
clearInterval(this. timer);
}
//开始轮播
start() {
this. timer = setInterval(this.fn.bind(this), 5000);
}
//点击圆点切换轮播图,停止自动轮播
clickDot(dotIndex) {
this.imgIndex = dotIndex - 1;
this.images.forEach(val => {
val.state = false;
});
this.images[dotIndex - 1].state = true;
this.stop();
}
blurDot() {
this.start();
}
//获取初始滑动位置
getStartX(e) {
this.stop();
this.startTime = Date.now();
const touch = e.touches[0] || e.changedTouches[0];
this.startX = touch.pageX;
}
// 获取滑动距离
getMoveX(e) {
const touch = e.touches[0] || e.changedTouches[0];
this.endX = touch.pageX;
}
// 滑动结束位置
getEndX(imgIndex) {
const dx = this.endX - this.startX;
const dTime = Date.now() - this.startTime;
if (Math.abs(dx) > this.screenWidth / 3 || (dTime < 300 && Math.abs(dx) > 30)) {
this.images.forEach(val => {
val.state = false;
});
// 右滑动
if (dx > 0) {
const leftDragIndex = imgIndex === this.images.length - 1 ? 0 : imgIndex + 1;
this.images[leftDragIndex].state = true;
} else {
// 左滑动
const rightDragIndex = imgIndex === 0 ? this.images.length - 1 : imgIndex - 1;
this.images[rightDragIndex].state = true;
}
}
//确保清空旧的定时器
this.stop();
this.start();
}
}
#### 3.css文件
div.container {
position: relative;
width: 100%;
height: 100%;
}
ul {
position:relative;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
li.activeLi {
z-index: 5;
}
li.imgP{
position: absolute;
list-style: none;
width: 100%;
height: 100%;
left: 0;
right: 0;
}
img {
border: none;
height: 100%;
width: 100%;
border-radius: 0 0 16px 16px;
}
div.dot{
position:absolute;
display:flex;
margin-top: 20px;
justify-content:center;
align-items:center;
z-index: 6;
}
div .circle{
float:left;
background: #fff;
width: 8px;
height: 8px;
border-radius: 50%;
}
div.active{
width: 20px;
height: 6px;
border-radius: 2px;
overflow: hidden;
border: 1px solid #FF5F5F;
background: #FF5F5F;
}
水平有限,互相学习,如有不足,感谢指正