将 Prev Next 控件添加到 Carousel
Posted
技术标签:
【中文标题】将 Prev Next 控件添加到 Carousel【英文标题】:Add Prev Next Controls to Carousel 【发布时间】:2021-09-16 14:37:15 【问题描述】:在玩弄了计时器和间隔之后,我找到了一个令我满意的解决方案。
请参阅relevant jsFiddle 或以下代码:
html:
<div id="foo">irrelevant content</div>
javascript(使用 jQuery):
var post_array = [ "abc", "123", "xyz" ];
var class_array = [ "red", "blue", "green" ];
var interval = 2000;
var i = 0;
var max = post_array.length;
var id ="#foo";
$(id).html(post_array[0]);
$(id).removeClass().addClass(class_array[0]);
setInterval( function()
++i;
$(id).fadeOut("slow", function()
$(id).html(post_array[i%max]).fadeIn("slow");
$(id).removeClass().addClass(class_array[i%max]);
);
, interval);
现在我想知道添加两个允许我回去和堡垒的侧箭头的最佳方法是什么。
我是否应该在命名函数中编写相关代码,以便在按下按钮时调用它并传递索引参数? (在这种情况下,我如何作用于同一个索引变量?) 按钮叠加的最佳做法是什么?
帮助! 提前致谢
【问题讨论】:
你做错了。 JS Carousel 代码应该是可重用的——而不是强迫您为最终的 N 个轮播复制/粘贴代码。创建自动播放意味着您还需要一个 hover-to-pausestop
方法。在 mouseenter 上你需要停止它,在 mouseleave 上你需要再次触发 play
方法......等等等等。这样,当你点击 PREV/NEXT 时,你不会得到不必要的故障和严重损坏的 UX。跨度>
shouldiuseacarousel.com
这似乎有点题外话,也许打开你自己的线程在那里讨论?
【参考方案1】:
轮播应该是模块化的、可重复使用和可扩展的。需要在 DOM 中添加另一个 Carousel 时,不要复制粘贴 JS 代码。
为了创建 PREV / NEXT 按钮,您还需要一个停止间隔的方法:stop
当您将鼠标悬停在轮播上时,您需要暂停自动播放以防止出现非常糟糕的用户体验 (UX)
不要使用 jQuery 制作动画。只需将 is-active
类分配给当前索引幻灯片即可制作动画,然后使用 CSS 对该类执行任何操作。
使用变量index
(以0开头)来跟踪当前幻灯片索引
You Might Not Need jQuery
旨在使用含糖的 class
或正确的 prototype
语法创建一个类实例 - 可以像这样使用:
const myCarousel = new Carousel(
target: "#carousel-one",
slides: [
title: "This is slide one",
image: "images/one.jpg"
,
title: "This is slide two! Yey.",
image: "images/two.jpg"
]
);
所以基本上,您需要一个具有这些方法的构造函数:
Method | Description |
---|---|
anim() |
Fix index if exceeds slides or is negative and animate to new index |
prev() |
Decrement index and trigger anim()
|
next() |
Increment index and trigger anim()
|
stop() |
Clear loop interval (On mouseenter) |
play() |
Start loop (Triggers next() every pause milliseconds) |
简单的 JavaScript 轮播示例
class Carousel
constructor(options)
Object.assign(this,
slides: [],
index: 0,
pause: 4000, // Pause between slides
EL: document.querySelector(options.target || "#Carousel"),
autoplay: true,
, options);
this.total = this.slides.length;
this.EL_area = this.EL.querySelector(".Carousel-area");
this.EL_prev = this.EL.querySelector(".Carousel-prev");
this.EL_next = this.EL.querySelector(".Carousel-next");
const NewEL = (tag, prop) => Object.assign(document.createElement(tag), prop);
// Preload images
this.ELs_items = this.slides.reduce((DF, item) =>
const EL_slide = NewEL("div",
className: "Carousel-slide"
);
const EL_image = NewEL("img",
className: "Carousel-image",
src: item.image,
alt: item.title
);
const EL_content = NewEL("div",
className: "Carousel-title",
textContent: item.title
);
EL_slide.append(EL_image, EL_content);
DF.push(EL_slide);
return DF;
, []);
this.EL_area.append(...this.ELs_items);
// Events
this.EL_prev.addEventListener("click", () => this.prev());
this.EL_next.addEventListener("click", () => this.next());
this.EL.addEventListener("mouseenter", () => this.stop());
this.EL.addEventListener("mouseleave", () => this.play());
// Init
this.anim();
this.play();
// Methods:
anim()
this.index = this.index < 0 ? this.total - 1 : this.index >= this.total ? 0 : this.index;
this.ELs_items.forEach((EL, i) => EL.classList.toggle("is-active", i === this.index));
prev()
this.index -= 1;
this.anim();
next()
this.index += 1;
this.anim();
stop()
clearInterval(this.itv);
play()
if (this.autoplay) this.itv = setInterval(() => this.next(), this.pause);
// Use like:
new Carousel(
target: "#carousel-one",
slides: [
title: "We're part of nature",
image: "https://picsum.photos/id/10/400/300"
,
title: "Remember to read and learn",
image: "https://picsum.photos/id/24/400/300"
,
title: "Up for a coffee?",
image: "https://picsum.photos/id/30/400/300"
,
]
);
/* CAROUSEL */
.Carousel
position: relative;
height: 300px;
max-height: 100vh;
.Carousel-slide
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transition: opacity 0.5s; /* DESIRED SLIDE TRANSITIONS */
opacity: 0; /* INACTIVE SLIDE*/
.Carousel-slide.is-active /* ACTIVE SLIDE! */
opacity: 1;
z-index: 1;
.Carousel-prev,
.Carousel-next
position: absolute;
z-index: 2;
top: 50%;
transform: translateY(-50%);
user-select: none; /* Prevent highlight */
.Carousel-prev
left: 1em;
.Carousel-next
right: 1em;
.Carousel-image
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
.Carousel-title
position: absolute;
width: 100%;
height: 100%;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 3em;
<div class="Carousel" id="carousel-one">
<div class="Carousel-area"></div>
<button class="Carousel-prev" type="button" aria-label="Previous slide">←</button>
<button class="Carousel-next" type="button" aria-label="Next slide">→</button>
<div class="Carousel-desc"></div>
</div>
使用上述代码,您可以在单个页面上拥有无限数量的轮播,因为每个轮播都有不同的target
ID。
PS:或者,如果您的代码跟踪上一个/下一个的方向,也可以编写增加/减少/环回当前索引的逻辑as(前面的伪代码!):
C = (is_next ? ++C : --C) < 0 ? T-1 : C%T;
C
是 当前 索引,T
是 总 幻灯片数,is_next
是一个布尔值,当方向是下一个。
【讨论】:
我可以看到我对轮播这个词的不当使用造成了一些混乱。不需要图像。只是为了澄清上面的代码只是一个最小的可重现示例来说明核心机制。我实际上是在 php 中生成内容,拉取 wordpress 自定义帖子,并在这个最小的艺术网站的首页上循环显示它们。 jQuery 已经在其中,不妨让我的生活更轻松,并使用它来保持我的代码低于十亿行。 @jmazzo 好吧,不要使用图像。 (删除所有使用 varEL_image
的代码)此外,即使我将上面的代码重写为 jQuery,它的行数也几乎相同。在这一点上,它只取决于你对 JS 的了解程度
@jmazzo 即:jsfiddle.net/3tv9nqyz - 花了大约 20 秒来删除不必要的代码。
我意识到我只是在澄清,我的方法只是让它快速运行,这太好了,谢谢。以上是关于将 Prev Next 控件添加到 Carousel的主要内容,如果未能解决你的问题,请参考以下文章
Google rel="next/prev" 用于动态分页?
使用 jQuery 动态添加 Prev Next 作为 Bootstrap Modal 按钮
为啥 jCarousel Next/Prev 按钮在添加项目后未启用