来自@DecjazMach的答案解决了最重要的问题,但并没有涵盖所有问题。例如,解决方案仍然使用第一个图像的宽度来设置可见滑块的宽度。这在很多情况下都是好的,但是如果第一张照片是一张瘦高的肖像,而其他的是风景画,或者反之亦然呢?
@Laiqa-Mohid也欢迎任何其他的建议,因此这里有一些来自于简化事情的建议,例如最小化JS中需要的计算和系统在点击时必须完成的“工作”。
http://bayeuxtapestry.rgspaces.org.uk/slider
笔记:
滑块可见部分的大小不依赖于第一个图像的尺寸
img已经被divs+背景图像所取代,这样就可以适应不同的大小/宽高比,而不需要任何javascript计算—这将自动帮助响应
这些div都具有相同的尺寸,因此滑块需要移动的量不取决于图像的大小
使用变换:translateX works但需要在Javascript中进行计算。我们可以使用CSS动画代替,只需要移动当前可见的幻灯片和下一个要显示的幻灯片。
图像服务有时不提供图像,所以我使用了我自己的-故意不同的大小和纵横比(包括肖像)
使用这种方法,可以有一个连续的滑块-显示第一张幻灯片,如果用户点击过去的最后一个。
<!DOCTYPE html>
<html>
<head>
<title>Slider</title>
<meta charset="utf-8">
<style>
#lookbook {
width: 100vw;
height: 100vh;
margin:0;
padding:0;
overflow:hidden;
}
.lookbook-nav {
width: 70vw;
height: 10vh;
margin-left: 15vw;
margin-top: 45vh;
position: absolute;
display: flex;
justify-content: space-between;
align-items: center;
}
button {
border: none;
outline: none;
background: transparent;
font-size: 2rem;
/* font-weight: bold; */
cursor: pointer;
}
.lookbook-nav button {
border: none;
outline: none;
background: transparent;
font-size: 2rem;
/* font-weight: bold; */
cursor: pointer;
}
button:hover {
opacity: 0.4;
}
div .lookbook {
width: 56vw;
}
.lookbook {
height: 91vh;
margin: auto;
overflow: hidden;
}
div.slider{
margin:0;
margin-top: 10vh;
height:81vh;/* this is height of (lookbook - margin-top) - probably better done through flex */
position:relative;
top:0;
padding:0;
width:100%;
}
@keyframes slideouttoleft {
from {
left: 0;
visibility:visible;
}
to {
left: -100%;
visibility:hidden;
}
}
@keyframes slideinfromright {
from {
left: 100%;
visibility:visible;
}
to {
left: 0;
visibility:visible;
}
}
@keyframes slideouttoright {
from {
left: 0;
visibility:visible;
}
to {
left: 100%;
visibility:hidden;
}
}
@keyframes slideinfromleft {
from {
left: -100%;
visibility:visible;
}
to {
left: 0;
visibility:visible;
}
}
.slider div {
position:absolute;
top:0;
left:0;
overflow:hidden;
visibility:hidden;
margin: 0;
padding: 0;
width:100%;
height:100%;
background-size: contain;
background-position: center center;
background-repeat: no-repeat no-repeat;
animation-duration: 0.4s;
animation-delay: 0s;
animation-iteration-count: 1;
animation-direction: normal;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
}
</style>
</head>
<body>
<div id="lookbook" data-tab-content class="black-text">
<div class="lookbook-nav">
<button id="left">â</button>
<button id="right">â</button>
</div>
<div class="lookbook">
<div class="slider">
<!-- images taken from Reading (UK) Museum's Victorian copy of the Bayeux Tapestry -->
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/boat-and-horses-768x546.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/two-horses-300x212.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/woman-and-child-1200x901.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/archer-2-768x1100.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/boat-builder-2-878x1024.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/group-1-768x603.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/pointing-horseman-768x853.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/group-2-768x619.png);"></div>
<div style="background-image:url(https://rgspaces.org.uk/bayeuxtapestry/wp-content/uploads/carrying-casket-768x556.png);"></div>
</div>
</div>
</div>
<script>
const slider = document.querySelector('.slider');
const sliderImages = document.querySelectorAll('.slider div');
const leftbtn = document.querySelector('#left');
const rightbtn = document.querySelector('#right');
const numImgs=sliderImages.length;
let curImg = 0;
rightbtn.addEventListener('click', () => {
sliderImages[curImg].style.animationName='slideouttoleft';
curImg=(curImg+1)%numImgs;
sliderImages[curImg].style.animationName='slideinfromright';
})
leftbtn.addEventListener('click', () => {
sliderImages[curImg].style.animationName='slideouttoright';
curImg=curImg==0? numImgs-1 : Math.abs((curImg-1)%numImgs);
sliderImages[curImg].style.animationName='slideinfromleft';
})
function initialize() {
sliderImages[0].style.animationName='slideinfromright';
}
window.onload=initialize;
</script>
</body>
</html>