javascript - 带有许多专辑的 Bootstrap 灯箱库
问题描述
我想在我的画廊网页中使用此代码,问题是当一张专辑幻灯片完成后,它应该再次从第一张图片开始。而且当我尝试打开第二张专辑时,它大部分时间都不会显示幻灯片。我认为每张幻灯片和当前幻灯片的计数存在一些问题。
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Verdana, sans-serif;
margin: 0;
}
* {
box-sizing: border-box;
}
.row > .column {
padding: 0 8px;
}
.row:after {
content: "";
display: table;
clear: both;
}
.column {
float: left;
width: 25%;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: black;
}
/* Modal Content */
.modal-content {
position: relative;
background-color: #fefefe;
margin: auto;
padding: 0;
width: 90%;
max-width: 1200px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
.mySlides {
display: none;
}
.cursor {
cursor: pointer;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* Number text (1/3 etc) */
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
img {
margin-bottom: -4px;
}
.caption-container {
text-align: center;
background-color: black;
padding: 2px 16px;
color: white;
}
.demo {
opacity: 0.6;
}
.active,
.demo:hover {
opacity: 1;
}
img.hover-shadow {
transition: 0.3s;
}
.hover-shadow:hover {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
</style>
<body>
<h2 style="text-align:center">Lightbox</h2>
<div class="row">
<div class="column">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" style="width:100%" onclick="openModal_1()" class="hover-shadow cursor">
</div>
<div class="column">
<img src="https://www.gstatic.com/webp/gallery/4.jpg" style="width:100%" onclick="openModal_2()" class="hover-shadow cursor">
</div>
</div>
<div id="myModal_1" class="modal">
<span class="close cursor" onclick="closeModal_1()">×</span>
<div class="modal-content">
<div class="mySlides">
<div class="numbertext">1 / 3</div>
<img src="https://www.gstatic.com/webp/gallery/1.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">2 / 3</div>
<img src="https://www.gstatic.com/webp/gallery/2.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">3 / 3</div>
<img src="https://www.gstatic.com/webp/gallery/3.jpg" style="width:100%">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
<div class="caption-container">
<p id="caption"></p>
</div>
</div>
</div>
<div id="myModal_2" class="modal">
<span class="close cursor" onclick="closeModal_2()">×</span>
<div class="modal-content">
<div class="mySlides">
<div class="numbertext">1 / 2</div>
<img src="https://www.gstatic.com/webp/gallery/4.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">2 / 2</div>
<img src="https://www.gstatic.com/webp/gallery/5.jpg" style="width:100%">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
<div class="caption-container">
<p id="caption"></p>
</div>
</div>
</div>
<script>
function openModal_1() {
document.getElementById("myModal_1").style.display = "block";
}
function openModal_2() {
document.getElementById("myModal_2").style.display = "block";
}
function closeModal_1() {
document.getElementById("myModal_1").style.display = "none";
}
function closeModal_2() {
document.getElementById("myModal_2").style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
}
</script>
</body>
</html>
解决方案
这是您似乎想要使用 Bootstrap 4 完成的示例,虽然未包含在您的问题中,但它被用作问题标签,所以我猜您正在使用它或至少想使用它:
使用标签:
/* added for SO example only, you probably don't need it */
.nav.nav-tabs {
margin: 1rem 0;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="container">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="slider-1-tab" data-toggle="tab" href="#slider-1" role="tab" aria-controls="slider-1" aria-selected="true">Slider 1</a>
</li>
<li class="nav-item">
<a class="nav-link" id="slider-2-tab" data-toggle="tab" href="#slider-2" role="tab" aria-controls="slider-2" aria-selected="false">Slider 2</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="slider-1" role="tabpanel" aria-labelledby="slider-1-tab">
<div id="carouselSlider-1" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselSlider-1" data-slide-to="0" class="active"></li>
<li data-target="#carouselSlider-1" data-slide-to="1"></li>
<li data-target="#carouselSlider-1" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/1.jpg" alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/2.jpg" alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/3.jpg" alt="Third slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselSlider-1" 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" href="#carouselSlider-1" 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 class="tab-pane" id="slider-2" role="tabpanel" aria-labelledby="slider-2-tab">
<div id="carouselSlider-2" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselSlider-2" data-slide-to="0" class="active"></li>
<li data-target="#carouselSlider-2" data-slide-to="1"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/4.jpg" alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/5.jpg" alt="Second slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselSlider-2" 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" href="#carouselSlider-2" 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>
诚然,它可以变得更智能。您可以拥有一个包含画廊结构的配置对象和一个从您的对象输出必要标记的函数。
config
带有选项卡和对象的通用示例:
在编译时从以下位置动态构建所有选项卡 + 滑块config
:
$(function() {
const galleryConfig = {
sliders: [{
id: 'slider-1',
title: 'Slider 1',
slides: [{
src: 'https://www.gstatic.com/webp/gallery/1.jpg',
alt: 'First slide'
}, {
src: 'https://www.gstatic.com/webp/gallery/2.jpg',
alt: 'Second slide'
}, {
src: 'https://www.gstatic.com/webp/gallery/3.jpg',
alt: 'Third slide'
}]
}, {
id: 'slider-2',
title: 'Slider 2',
slides: [{
src: 'https://www.gstatic.com/webp/gallery/4.jpg',
alt: 'First slide'
}, {
src: 'https://www.gstatic.com/webp/gallery/5.jpg',
alt: 'Second slide'
}]
}]
};
function generateSliders(config) {
let navs = $('<ul />', {
role: 'tablist',
class: 'nav nav-tabs'
});
let tabs = $('<div />', {
class: 'tab-content'
})
config.sliders.forEach((slider, index) => {
let $li = $('<li />', {
class: 'nav-item',
html: $('<a />', {
class: 'nav-link' + (index ? '' : ' active'),
id: `slider-${index + 1}-tab`,
'data-toggle': 'tab',
href: `#slider-${index + 1}`,
role: 'tab',
'aria-controls': `#slider-${index + 1}`,
'aria-selected': index ? 'false' : 'true',
text: slider.title
})
});
$li.appendTo(navs);
});
navs.appendTo($('#galleryContainer'));
config.sliders.forEach((slider, index) => {
let $tab = $('<div />', {
class: 'tab-pane' + (index ? '' : ' active'),
id: slider.id,
role: 'tabpanel',
'aria-labelledby': `${slider.id}-tab`,
html: $('<div />', {
class: 'carousel slide',
'data-ride': 'carousel',
id: `carouselSlider-${index + 1}`,
html: $('<ol />', {
class: 'carousel-indicators',
html: slider.slides.map((s, i) => $('<li />', {
'data-target': `#carouselSlider-${index + 1}`,
'data-slide-to': `${i}`,
class: i ? '' : 'active'
})[0].outerHTML).join('')
})[0].outerHTML
+ $('<div />', {
class: 'carousel-inner',
html: slider.slides.map((s, i) => $('<div />', {
class: 'carousel-item' + (i ? '' : ' active'),
html: $('<img />', {
class: 'd-block w-100',
src: s.src,
alt: s.alt
})
})[0].outerHTML).join('')
})[0].outerHTML
+ $('<a />', {
class: 'carousel-control-prev',
href: `#carouselSlider-${index + 1}`,
role: 'button',
'data-slide': 'prev',
html: $('<span />', {
class: 'carousel-control-prev-icon',
'aria-hidden': 'true'
})[0].outerHTML
+ $('<span />', {
class: 'sr-only',
text: 'Previous'
})[0].outerHTML
})[0].outerHTML
+ $('<a />', {
class: 'carousel-control-next',
href: `#carouselSlider-${index + 1}`,
role: 'button',
'data-slide': 'next',
html: $('<span />', {
class: 'carousel-control-next-icon',
'aria-hidden': 'true'
})[0].outerHTML
+ $('<span />', {
class: 'sr-only',
text: 'Next'
})[0].outerHTML
})[0].outerHTML
})
});
$tab.appendTo(tabs)
})
tabs.appendTo($('#galleryContainer'));
}
generateSliders(galleryConfig);
})
/* added for SO example only, you probably don't need it */
.nav.nav-tabs {
margin: 1rem 0;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="container">
<div id="galleryContainer"></div>
</div>
显然,您的配置对象可以从外部源加载。这只是一个概念证明。所做的是generateSliders()
遍历配置对象中的每个滑块并输出必要的 Bootstrap 4 标记,因此您不必这样做,特别是因为很容易错过 aria 属性,恕我直言,应该避免手动操作,在可能的情况。
使用模态:
.modal-launchers img {
width: 100px;
height: auto;
display: inline-block;
margin-right: 1rem;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="col modal-launchers">
<a id="modal-link-1" href="#modal-1" data-toggle="modal" data-target="#modal-1">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" alt="First slider">
</a>
<a id="modal-link-2" href="#modal-2" data-toggle="modal" data-target="#modal-2">
<img src="https://www.gstatic.com/webp/gallery/4.jpg" alt="Second slider"></a>
</div>
</div>
</div>
<div class="modal fade" id="modal-1" tabindex="-1" role="dialog" aria-labelledby="modal-link-1" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">First gallery</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="carouselSlider-1" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselSlider-1" data-slide-to="0" class="active"></li>
<li data-target="#carouselSlider-1" data-slide-to="1"></li>
<li data-target="#carouselSlider-1" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/1.jpg" alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/2.jpg" alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/3.jpg" alt="Third slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselSlider-1" 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" href="#carouselSlider-1" 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>
</div>
<div class="modal fade" id="modal-2" tabindex="-1" role="dialog" aria-labelledby="modal-link-2" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Second gallery</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="carouselSlider-2" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselSlider-2" data-slide-to="0" class="active"></li>
<li data-target="#carouselSlider-2" data-slide-to="1"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/4.jpg" alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="https://www.gstatic.com/webp/gallery/5.jpg" alt="Second slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselSlider-2" 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" href="#carouselSlider-2" 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>
</div>
同样,只是一个例子。您需要做的就是继续阅读 Bootstrap 的文档,从示例中获取标记并将其应用到您的代码中。
带有模态和config
对象的通用示例:
在编译时从以下位置动态构建所有模式 + 滑块config
:
$(function() {
const galleryConfig = {
sliders: [{
id: 'slider-1',
title: 'Slider 1',
slides: [{
src: 'https://picsum.photos/id/230/800/600',
alt: 'First slide'
}, {
src: 'https://picsum.photos/id/231/800/600',
alt: 'Second slide'
}, {
src: 'https://picsum.photos/id/232/800/600',
alt: 'Third slide'
}]
}, {
id: 'slider-2',
title: 'Slider 2',
slides: [{
src: 'https://picsum.photos/id/233/800/600',
alt: 'First slide'
}, {
src: 'https://picsum.photos/id/234/800/600',
alt: 'Second slide'
}, {
src: 'https://picsum.photos/id/235/800/600',
alt: 'Third slide'
}, {
src: 'https://picsum.photos/id/236/800/600',
alt: 'Fourth slide'
}, {
src: 'https://picsum.photos/id/237/800/600',
alt: 'Fifth slide'
}]
}]
};
function generateModals(config) {
let navs = $('#galleryContainer');
config.sliders.forEach((slider, i) => {
let $launcher = $('<a />', {
id: `modal-link-${i}`,
href: `#gallery-modal-${i}`,
'data-target': `#gallery-modal-${i}`,
'data-toggle': 'modal',
title: slider.title,
html: slider.slides.map(image => $('<img />', {
src: image.src,
alt: image.title
})).map(o => o[0].outerHTML).join('')
});
$launcher.appendTo(navs);
});
navs.appendTo($('#galleryContainer'));
config.sliders.forEach((slider, i) => {
let $modalDiv = $('<div />', {
class: 'modal fade',
id: `gallery-modal-${i}`,
role: 'dialog',
'aria-labelledby': `modal-link-${i}`,
'aria-hidden': 'true',
html: $('<div />', {
class: 'modal-dialog modal-lg',
role: 'document',
html: $('<div />', {
class: 'modal-content',
html: $('<div />', {
class: 'modal-header',
html: $('<h5 />', {
class: 'modal-title',
text: slider.title
})[0].outerHTML +
$('<button />', {
type: 'button',
class: 'close',
'data-dismiss': 'modal',
'aria-label': 'Close',
html: $('<span />', {
'aria-hidden': 'true',
html: '×'
})
})[0].outerHTML
})[0].outerHTML +
$('<div />', {
class: 'modal-body',
html: $('<div />', {
class: 'carousel slide',
'data-ride': 'carousel',
id: `carouselSlider-${i}`,
html: $('<ol />', {
class: 'carousel-indicators',
html: slider.slides.map((o, k) => $('<li />', {
'data-target': `#carouselSlider-${i}`,
'data-slide-to': `${k}`,
class: k ? '' : 'active'
})[0].outerHTML).join('')
})[0].outerHTML +
$('<div />', {
class: 'carousel-inner',
html: slider.slides.map((o, k) => $('<div />', {
class: 'carousel-item' + (k ? '' : ' active'),
html: $('<img />', {
class: 'd-block w-100',
src: o.src,
alt: o.alt
})
})[0].outerHTML).join('')
})[0].outerHTML +
$('<a />', {
class: 'carousel-control-prev',
href: `#carouselSlider-${i}`,
role: 'button',
'data-slide': 'prev',
html: $('<span />', {
class: 'carousel-control-prev-icon',
'aria-hidden': 'true'
})[0].outerHTML +
$('<span />', {
class: 'sr-only',
text: 'Previous'
})[0].outerHTML
})[0].outerHTML +
$('<a />', {
class: 'carousel-control-next',
href: `#carouselSlider-${i}`,
role: 'button',
'data-slide': 'next',
html: $('<span />', {
class: 'carousel-control-next-icon',
'aria-hidden': 'true'
})[0].outerHTML +
$('<span />', {
class: 'sr-only',
text: 'Next'
})[0].outerHTML
})[0].outerHTML
})
})[0].outerHTML
})
})
});
$modalDiv.appendTo($('body'))
})
}
generateModals(galleryConfig);
})
#galleryContainer img {
height: 72px;
width: auto;
display: block;
margin: 0 1px 1px 0;
}
#galleryContainer a {
margin: 0 0 -1px;
padding: .5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
transition: background-color .3s ease-out;
background-color:transparent;
}
#galleryContainer a:hover {
background-color: #f5f5f5;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="col">
<div id="galleryContainer"></div>
</div>
</div>
</div>
推荐阅读
- typescript - 如何通过考虑 Typescript 中字符串数组中元素的名称来删除元素
- php - php - mysqli - 如果不存在则创建数据库
- c# - 在将 Azure Key Vault 配置提供程序用于机密/配置时使用 IConfiguration 方法,例如 Bind 和 GetConnectionString
- javascript - 如何转换这两个数据结构?
- java - 为什么我们在登录过程中使用异步,即使我们必须等待结果?
- python - 使用 SQLAlchemy 迁移数据库(sqlite 到 Postgres CloudSQL)
- javascript - 为 HTML DOM 创建元素
- ios - 反应本机 - 相机胶卷返回的 uri 没有文件的扩展名
- android - 在解决构建路径错误之前无法构建 Flutter
- vb.net - 将文本写入 .txt 文件的通用代码?