angular - 如何向这个 Angular 轮播添加无限滚动?
问题描述
我关注了这篇精彩的文章,它演示了如何在 Angular 中使用两个指令和一个组件制作一个简单的轮播。
功能集非常有限,不包括我想添加的“无限滚动”模式。
通过'无限滚动' - 我的意思是这样的jQuery等价物:
var carousel = $('#carousel'),
threshold = 150,
slideWidth = 500,
dragStart,
dragEnd;
$('#next').click(function() {
shiftSlide(-1)
})
$('#prev').click(function() {
shiftSlide(1)
})
carousel.on('mousedown', function() {
if (carousel.hasClass('transition')) return;
dragStart = event.pageX;
$(this).on('mousemove', function() {
dragEnd = event.pageX;
$(this).css('transform', 'translateX(' + dragPos() + 'px)')
})
$(document).on('mouseup', function() {
if (dragPos() > threshold) {
return shiftSlide(1)
}
if (dragPos() < -threshold) {
return shiftSlide(-1)
}
shiftSlide(0);
})
});
function dragPos() {
return dragEnd - dragStart;
}
function shiftSlide(direction) {
if (carousel.hasClass('transition')) return;
dragEnd = dragStart;
$(document).off('mouseup')
carousel.off('mousemove')
.addClass('transition')
.css('transform', 'translateX(' + (direction * slideWidth) + 'px)');
setTimeout(function() {
if (direction === 1) {
$('.slide:first').before($('.slide:last'));
} else if (direction === -1) {
$('.slide:last').after($('.slide:first'));
}
carousel.removeClass('transition')
carousel.css('transform', 'translateX(0px)');
}, 700)
}
$carousel-width: 600px;
$carousel-height: 300px;
body {
background: #333;
color: #fff;
font-size: 22pt;
text-align: center;
font-family: 'Teko';
letter-spacing: 0.15em;
}
body * {
-webkit-user-select: none
}
.wrap {
position: relative;
width: $carousel-width;
height: 300px;
margin: 0 auto;
box-shadow: 7px 7px 5px 0px rgba(0, 0, 0, 0.25);
}
.window {
overflow: hidden;
position: relative;
background: #222;
}
#carousel {
width: 10000px;
position: relative;
top: 0;
left: -450px;
}
.slide {
height: 300px;
width: 500px;
cursor: pointer;
float: left;
display: flex;
flex-direction: column;
justify-content: center;
}
.slide#b1 {
background: #556270
}
.slide#b2 {
background: #4ECDC4
}
.slide#b3 {
background: #9CE462
}
.slide#b4 {
background: #FF6B6B
}
.slide#b5 {
background: #C44D33
}
#prev,
#next {
cursor: pointer;
position: absolute;
bottom: -40px;
font-size: 14pt;
}
#prev {
left: 0
}
#next {
right: 0
}
.transition {
transition: .7s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>INFINITE CAROUSEL</h1>
<div class="wrap">
<div class="window">
<div id="carousel">
<span class="slide" id="b1">SLIDE-1</span>
<span class="slide" id="b2">SLIDE-2</span>
<span class="slide" id="b3">SLIDE-3</span>
<span class="slide" id="b4">SLIDE-4</span>
<span class="slide" id="b5">SLIDE-5</span>
</div>
</div>
<span id="prev">PREV</span>
<span id="next">NEXT</span>
</div>
(旋转木马可以在每个方向无限滚动,同时保持幻灯片的正确顺序)
我尝试了多种方法来添加此功能,但都没有成功,我尝试过(随后删除):
在当前查看的子集的任一侧动态添加和删除幻灯片块 - 即,如果轮播包含 3 张幻灯片,我将在原始 `1-2-3 1-2-3 的任一侧复制它们,然后添加/删除块为用户滚动。这几乎奏效了,唯一的问题是 Angular 在删除块并疯狂地旋转轮播时感到困惑,因为它仍然引用了一个不再存在的幻灯片编号。
动态添加和删除单个幻灯片,类似于上述方法。同样的问题。
直接复制幻灯片数百次。这行得通,但显然非常糟糕,而且看起来很愚蠢。
这是一个堆栈闪电战,展示了我到目前为止所拥有的东西。
解决方案
更新 (在我重新排序查询列表之前,当我们在最后一个但在第二个滑块中时)
有一个解决方法。关键是重新排序 QueryList 并在您处于最后一个(在进行下一个之前)或第一个(在进行上一个之前)时更改 currentSlide
首先更改函数 transitionCarrousel 以允许在 0 秒内“动画”
private buildAnimation(offset, time: any) {
return this.builder.build([
animate(time == null ? this.timing : 0,
style({ transform: `translateX(-${offset}px)` }))
]);
}
next 和 prev 的功能变成了
next() {
//if we are in the last
if (this.currentSlide + 1 == this.items.length) {
//reorder the QueryList,
let arr = this.items.toArray();
let first = arr.shift(); //remove the first element
arr = arr.concat([first]); //Concat at last of the array
this.items.reset(arr);
this.currentSlide--; //less currentSlide
this.transitionCarousel(0); //execute the animation in 0 seconds
}
this.currentSlide = (this.currentSlide + 1) % this.items.length;
this.transitionCarousel(null);
}
prev() {
//If we are in the first one
if (this.currentSlide == 0) {
let arr = this.items.toArray();
let last = arr.pop(); //remove the last element
arr = [last].concat(arr); //create an array with the last element+arr
this.items.reset(arr);
this.currentSlide++; //change the currentSlide
this.transitionCarousel(0); //execute the animation in 0 seconds
}
this.currentSlide =
(this.currentSlide - 1 + this.items.length) % this.items.length;
this.transitionCarousel(null);
}
您可以在stackblitz中看到工作
推荐阅读
- java - 从另一个类设置 TextView 文本
- python - Python:从列表中删除字符
- regex - 正则表达式:抓取分配给属性的 JS 函数的内容
- reactjs - 如何在 Draftjs 中突出显示文本
- node.js - Sails.js:由于用法不明确,无法填充模型
- android - Firebase 云消息传递:Oreo 中的通知图标问题
- spring-boot - Zipkin UI 显示错误消息“错误:无法加载服务名称:无可用消息”
- apache-flink - 在不中断执行的情况下更改 Flink 中的源函数
- openrefine - OpenRefine:“填充”替换一列中的值
- oop - UML继承-为什么箭头的方向是从子类到父类?