英文:
Implementing a Dynamic Filterable Carousel
问题
细节:
我目前正在使用Bootstrap构建一个走马灯,但在使其正确显示方面遇到了一些挑战。以下是我试图实现的概述:
- 走马灯最初是空的。
- 点击按钮(将充当过滤器的作用)后,我想用包含图像的div来填充走马灯。当点击按钮(例如,“汽车”)时,只应将汽车的图像添加到走马灯中。单击标有“全部”的按钮应将所有可用图像添加到走马灯中。
要求:
- 在走马灯中同时显示四个瓦片。
- 我希望动态走马灯的响应方式与普通走马灯类似,循环显示所有实体。例如,1、2、3、4、5、1、2、3...等。
- 根据点击的按钮向走马灯添加元素。
我尝试过的:
我有一个正常运行的走马灯,你可以在这里找到:jsfiddle 链接
HTML:
<!-- 走马灯 -->
<div class="desktop-carousel">
<div class="container text-center">
<div class="row mx-auto my-auto">
<div id="myCarousel" class="carousel slide w-100" data-ride="carousel">
<div class="carousel-inner w-100" role="listbox">
<div class="carousel-item active">
<div class="col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="http://via.placeholder.com/272x192?text=1" loading="lazy" onerror="imgError()">
</a>
</div>
</div>
<!-- 其他轮播项... -->
</div>
<!-- 控制按钮... -->
</div>
</div>
</div>
</div>
JavaScript:
// 走马灯 //
$('#myCarousel').carousel({
interval: 2500
});
$('.carousel .carousel-item').each(function() {
var minPerSlide = 4;
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
for (var i = 0; i < minPerSlide; i++) {
next = next.next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
}
});
然而,我在使动态走马灯按预期工作方面遇到了困难。
这里是链接:jsfiddle 链接
HTML:
<button id="addItemButton" onclick="filterSelection()">向走马灯添加项目</button>
<button id="clearCarousel" onclick="clearCarousel()">从走马灯中清除项目</button>
<div class="container text-center">
<div class="row mx-auto my-auto">
<div id="myCarousel" class="carousel slide w-100" data-ride="carousel">
<div class="carousel-inner w-100" role="listbox"></div>
<a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev">
上一个
</a>
<a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next">
下一个
</a>
</div>
</div>
</div>
JavaScript:
// 创建走马灯 //
function filterSelection() {
var carouselData = [
{
imageUrl: "http://via.placeholder.com/272x192?text=1",
name: "Hannon"
},
// 其他项目...
];
var carouselInner = $('.carousel-inner');
var count = 0;
// 向走马灯添加项目
carouselData.forEach(function(item, index) {
if (count == 0) {
console.log('Inside If');
var isActive = (index === 0) ? "active" : "";
var itemHtml = `
<div class="carousel-item ${isActive}">
<div class="carousel-item-content col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="${item.imageUrl}" alt="${item.name}">
</a>
</div>
</div>
`;
carouselInner.append(itemHtml);
} else {
console.log('In Else')
var isActive = (index === 0) ? "active" : "";
var itemHtml = `
<div class="carousel-item">
<div class="carousel-item-content col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="${item.imageUrl}" alt="${item.name}">
</a>
</div>
</div>
`;
carouselInner.append(itemHtml);
}
count++;
});
// 初始化走马灯
$('#myCarousel').carousel();
}
// 运行走马灯 //
$('#myCarousel').carousel({
interval: 1500
});
$('.carousel .carousel-item').each(function() {
var minPerSlide = 4;
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
for (var i = 0; i < minPerSlide; i++) {
next = next.next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
}
});
function clearCarousel() {
$('.carousel-inner').empty();
$('#myCarousel').carousel('dispose');
}
我将不胜感激地接受您提供的任何建议、替代方法、解决方案或指导。
英文:
Details:
I'm currently working on building a carousel with bootstrap, and I'm facing some challenges in making it display correctly. Here's an overview of what I'm trying to achieve:
- Initially, the carousel is empty.
- Upon clicking a button (which would act like a filter), I want to populate the carousel with divs that contain images. When a button is clicked (e.g., "cars"), only images of cars should be added to the carousel. Clicking a button labeled "all" should add all available images to the carousel.
Requirements:
- Display four tiles at a time in the carousel.
- I want the dynamic carousel to respond similarly to the normal carousel, rotating through all entities. For example, 1, 2, 3, 4, 5, 1, 2, 3... etc.
- Add elements to the carousel based on the button clicked.
What i have tried:
I have a functioning normal carousel that you can find here: jsfiddle link
HTML:
<!--Carousel-->
<div class="desktop-carousel">
<div class="container text-center">
<div class="row mx-auto my-auto">
<div id="myCarousel" class="carousel slide w-100" data-ride="carousel">
<div class="carousel-inner w-100" role="listbox">
<div class="carousel-item active">
<div class="col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="http://via.placeholder.com/272x192?text=1" loading="lazy" onerror="imgError()">
</a>
</div>
</div>
<div class="carousel-item">
<div class="col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="http://via.placeholder.com/272x192?text=2" loading="lazy">
<p class="name items">Self care</p>
</a>
</div>
</div>
<div class="carousel-item">
<div class="col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="http://via.placeholder.com/272x192?text=3" loading="lazy">
<p class="name items">Pain</p>
</a>
</div>
</div>
<div class="carousel-item">
<div class="col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="http://via.placeholder.com/272x192?text=4" loading="lazy">
<p class="name items">Self care</p>
</a>
</div>
</div>
<div class="carousel-item">
<div class="col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="http://via.placeholder.com/272x192?text=5" loading="lazy">
<p class="name items">Hepilor</p>
</a>
</div>
</div>
</div>
<a class="carousel-control-prev bg-dark w-auto" href="#myCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next bg-dark w-auto" href="#myCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
JavaScript:
// Carousel //
$('#myCarousel').carousel({
interval: 2500
});
$('.carousel .carousel-item').each(function() {
var minPerSlide = 4;
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
for (var i = 0; i < minPerSlide; i++) {
next = next.next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
}
});
However, I'm struggling to make the dynamic carousel work as intended.
Here is a link to it: jsfiddle link
HTML:
<button id="addItemButton" onclick="filterSelection()">Add Items to Carousel</button>
<button id="clearCarousel" onclick="clearCarousel()">Clear Items From Carousel</button>
<div class="container text-center">
<div class="row mx-auto my-auto">
<div id="myCarousel" class="carousel slide w-100" data-ride="carousel">
<div class="carousel-inner w-100" role="listbox"></div>
<a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev">
Previous
</a>
<a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next">
Next
</a>
</div>
</div>
</div>
JavaScript:
// Create Carousel //
function filterSelection() {
var carouselData = [{
imageUrl: "http://via.placeholder.com/272x192?text=1",
name: "Hannon"
},
{
imageUrl: "http://via.placeholder.com/272x192?text=2",
name: "Self care"
},
{
imageUrl: "http://via.placeholder.com/272x192?text=3",
name: "Pain"
},
{
imageUrl: "http://via.placeholder.com/272x192?text=4",
name: "Self care"
},
{
imageUrl: "http://via.placeholder.com/272x192?text=5",
name: "Hepilor"
}
];
var carouselInner = $('.carousel-inner');
var count = 0;
// Add items to carousel
carouselData.forEach(function(item, index) {
if (count == 0) {
console.log('Inside If');
var isActive = (index === 0) ? "active" : "";
var itemHtml = `
<div class="carousel-item ${isActive}">
<div class="carousel-item-content col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="${item.imageUrl}" alt="${item.name}">
</a>
</div>
</div>
`;
carouselInner.append(itemHtml);
} else {
console.log('In Else')
var isActive = (index === 0) ? "active" : "";
var itemHtml = `
<div class="carousel-item">
<div class="carousel-item-content col-lg-3 col-md-5">
<a href="#">
<img class="img-fluid" src="${item.imageUrl}" alt="${item.name}">
</a>
</div>
</div>
`;
carouselInner.append(itemHtml);
}
count++;
});
// Initialize the carousel
$('#myCarousel').carousel();
}
// Run carousel //
$('#myCarousel').carousel({
interval: 1500
});
$('.carousel .carousel-item').each(function() {
var minPerSlide = 4;
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
for (var i = 0; i < minPerSlide; i++) {
next = next.next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
}
});
function clearCarousel() {
$('.carousel-inner').empty();
$('#myCarousel').carousel('dispose');
}
I would greatly appreciate any suggestions, alternative approaches, solutions, or guidance you can provide.
答案1
得分: 1
这是一个简单的轮播图,一次显示一个项目,可以使用过滤器工作。 这些过滤器易于理解和使用(可以添加更多过滤器和/或修改现有过滤器)。 如果需要,可以扩展它以显示多个元素。
const cars = [
"https://cdn.motor1.com/images/mgl/3KmYR/s4/genesis-g80-exterior.webp",
"https://cdn.motor1.com/images/mgl/yM93o/s4/honda-civic-type-r-exterior.webp",
"https://cdn.motor1.com/images/mgl/KjMYQ/s4/bugatti-divo-exterior.webp"
];
const buildings = [
"https://ychef.files.bbci.co.uk/1280x720/p0db81jf.jpg",
"https://ychef.files.bbci.co.uk/1600x900/p0db827c.webp"
];
const dogs = [
"https://hips.hearstapps.com/hmg-prod/images/dog-puppy-on-garden-royalty-free-image-1586966191.jpg?crop=0.752xw:1.00xh;0.175xw,0&resize=1200:*",
"https://publish.purewow.net/wp-content/uploads/sites/2/2021/06/smallest-dog-breeds-toy-poodle.jpg?fit=728%2C524",
"https://www.cdc.gov/healthypets/images/pets/cute-dog-headshot.jpg?_=42445",
"https://www.thetimes.co.uk/imageserver/image/%2Fmethode%2Ftimes%2Fprod%2Fweb%2Fbin%2Fc47f6830-9292-11ed-b04f-b9bf191ef388.jpg?crop=5879%2C3919%2C0%2C0"
];
const filters = {
all: [...cars, ...buildings, ...dogs],
cars,
buildings,
dogs
};
const carousel = document.getElementById("carousel");
const carouselNavigation = document.getElementById("carouselNavigation");
function selectFilter(button) {
button.parentElement.querySelector(".active")?.classList.remove("active");
const filter = button.getAttribute("value");
button.classList.add("active");
carousel.innerHTML = "";
carouselNavigation.innerHTML = "";
const thisFilterElementsNumber = filters[filter].length - 1;
filters[filter].forEach((url, index) => {
carousel.innerHTML += `
<div id="carouselSlide${index}" class="carouselSlide">
<div class="carouselSnapper"></div>
<a href="#carouselSlide${index === 0 ? thisFilterElementsNumber : (index - 1)}" class="carouselPrev"></a>
<a href="#carouselSlide${index === thisFilterElementsNumber ? 0 : (index + 1)}" class="carouselNext"></a>
<img src="${url}">
</div>
`;
carouselNavigation.innerHTML += `<a href="#carouselSlide${index}" class="carouselNavigationButton"></a>`;
});
}
selectFilter(document.querySelector(`[value="all"]`));
/* CSS部分未翻译,保留原文 */
<div class="filters">
<p class="filterButton" onclick="selectFilter(this);" value="all">All</p>
<p class="filterButton" onclick="selectFilter(this);" value="cars">Cars</p>
<p class="filterButton" onclick="selectFilter(this);" value="buildings">Buildings</p>
<p class="filterButton" onclick="selectFilter(this);" value="dogs">Dogs</p>
</div>
<div class="carousel">
<div class="carouselViewport" id="carousel"></div>
<div class="carouselNavigation" id="carouselNavigation"></div>
</div>
英文:
Here is a simple carousel that shows one item at a time that works with filters. The filters are easy to understand and work with (adding more filters and/or modifying existing ones). You can expand it to show more than one element if needed.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const cars = [
"https://cdn.motor1.com/images/mgl/3KmYR/s4/genesis-g80-exterior.webp",
"https://cdn.motor1.com/images/mgl/yM93o/s4/honda-civic-type-r-exterior.webp",
"https://cdn.motor1.com/images/mgl/KjMYQ/s4/bugatti-divo-exterior.webp"
];
const buildings = [
"https://ychef.files.bbci.co.uk/1280x720/p0db81jf.jpg",
"https://ychef.files.bbci.co.uk/1600x900/p0db827c.webp"
];
const dogs = [
"https://hips.hearstapps.com/hmg-prod/images/dog-puppy-on-garden-royalty-free-image-1586966191.jpg?crop=0.752xw:1.00xh;0.175xw,0&resize=1200:*",
"https://publish.purewow.net/wp-content/uploads/sites/2/2021/06/smallest-dog-breeds-toy-poodle.jpg?fit=728%2C524",
"https://www.cdc.gov/healthypets/images/pets/cute-dog-headshot.jpg?_=42445",
"https://www.thetimes.co.uk/imageserver/image/%2Fmethode%2Ftimes%2Fprod%2Fweb%2Fbin%2Fc47f6830-9292-11ed-b04f-b9bf191ef388.jpg?crop=5879%2C3919%2C0%2C0"
];
const filters = {
all: [...cars, ...buildings, ...dogs],
cars,
buildings,
dogs
};
const carousel = document.getElementById("carousel");
const carouselNavigation = document.getElementById("carouselNavigation");
function selectFilter(button) {
button.parentElement.querySelector(".active")?.classList.remove("active");
const filter = button.getAttribute("value");
button.classList.add("active");
carousel.innerHTML = "";
carouselNavigation.innerHTML = "";
const thisFilterElementsNumber = filters[filter].length - 1;
filters[filter].forEach((url, index) => {
carousel.innerHTML += `
<div id="carouselSlide${index}" class="carouselSlide">
<div class="carouselSnapper"></div>
<a href="#carouselSlide${index === 0 ? thisFilterElementsNumber : (index - 1)}" class="carouselPrev"></a>
<a href="#carouselSlide${index === thisFilterElementsNumber ? 0 : (index + 1)}" class="carouselNext"></a>
<img src="${url}">
</div>
`;
carouselNavigation.innerHTML += `<a href="#carouselSlide${index}" class="carouselNavigationButton"></a>`;
});
}
selectFilter(document.querySelector(`[value="all"]`));
<!-- language: lang-css -->
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
user-select: none;
}
* {
box-sizing: border-box;
}
*::-webkit-scrollbar {
width: 0px;
height: 0px;
}
/* Filter */
.filters {
position: relative;
width: 400px;
height: auto;
margin: 10px auto;
}
.filterButton {
display: inline-block;
position: relative;
width: fit-content;
height: auto;
color: #ffffff;
background-color: #555555;
border-radius: 999px;
padding: 5px 10px;
cursor: pointer;
}
.filterButton.active {
background-color: #111111;
}
/* Carousel */
.carousel {
position: relative;
width: 400px;
height: 200px;
margin: 10px auto;
perspective: 100px;
}
.carousel::before,
.carousel::after,
.carouselPrev,
.carouselNext {
position: absolute;
top: 50%;
width: 40px;
height: 40px;
font-size: 0;
border-radius: 999px;
transform: translateY(-50%);
}
.carousel::before,
.carouselPrev {
left: 10px;
}
.carousel::after,
.carouselNext {
right: 10px;
}
.carousel::before,
.carousel::after {
content: "";
font-size: 20px;
text-align: center;
color: #fff;
background-position: center center;
background-size: 20px 20px;
background-repeat: no-repeat;
background-color: #222222;
pointer-events: none;
z-index: 1;
}
.carousel::before {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='0,50 80,100 80,0' fill='%23fff'/%3E%3C/svg%3E");
}
.carousel::after {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='100,50 20,100 20,0' fill='%23fff'/%3E%3C/svg%3E");
}
.carouselViewport {
display: flex;
position: absolute;
width: 100%;
height: 100%;
border-radius: 10px;
overflow-x: scroll;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
.carouselSlide {
position: relative;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
flex: 0 0 100%;
}
.carouselSnapper {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
scroll-snap-align: center;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.carouselNavigation {
position: absolute;
width: 100%;
height: auto;
top: 100%;
left: 0px;
text-align: center;
margin-top: 5px;
}
.carouselNavigationButton {
display: inline-block;
width: 14px;
height: 14px;
background-color: #222222;
border-radius: 999px;
transition: transform 0.1s;
margin: 0px 5px;
}
<!-- language: lang-html -->
<div class="filters">
<p class="filterButton" onclick="selectFilter(this);" value="all">All</p>
<p class="filterButton" onclick="selectFilter(this);" value="cars">Cars</p>
<p class="filterButton" onclick="selectFilter(this);" value="buildings">Buildings</p>
<p class="filterButton" onclick="selectFilter(this);" value="dogs">Dogs</p>
</div>
<div class="carousel">
<div class="carouselViewport" id="carousel"></div>
<div class="carouselNavigation" id="carouselNavigation"></div>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论