如何制作一个无限的 JS 轮播(无穷大问题)
Posted
技术标签:
【中文标题】如何制作一个无限的 JS 轮播(无穷大问题)【英文标题】:How to make an infinite JS Carousel ( infinity problem) 【发布时间】:2020-02-03 05:04:43 【问题描述】:试图制作一个无限旋转木马,它会以我选择的位置为中心。 轮播应该循环播放,目前我只在一侧实现了效果,我的主要问题是过渡是可见的。
我需要达到的效果是,当您单击轮播时,循环是无限的,但您看不到从一端到另一端的闪烁,我对 Web 开发相对较新,因此将不胜感激。 提前致谢!
html:
<div class="content__bottom">
<div class="service__block" data-name="instagram" data-order="1">
<i class="service__block--icon fab fa-instagram"></i>
<h5 class="service__block--title">אינסטגרם</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="facebook" data-order="2">
<i class="service__block--icon fab fa-facebook-f"></i>
<h5 class="service__block--title">פייסבוק</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="youtube" data-order="3">
<i class="service__block--icon fab fa-youtube"></i>
<h5 class="service__block--title">יוטיוב</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="twitch" data-order="4">
<i class="service__block--icon fab fa-twitch"></i>
<h5 class="service__block--title">טוויץ</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="twitter" data-order="5">
<i class="service__block--icon fab fa-twitter"></i>
<h5 class="service__block--title">טוויטר</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="pinterest" data-order="6">
<i class="service__block--icon fab fa-pinterest"></i>
<h5 class="service__block--title">פינטרסט</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="soundcloud" data-order="7">
<i class="service__block--icon fab fa-soundcloud"></i>
<h5 class="service__block--title">סאונדקלאוד</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="spotify" data-order="8">
<i class="service__block--icon fab fa-spotify"></i>
<h5 class="service__block--title">ספוטיפי</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="telegram" data-order="9">
<i class="service__block--icon fab fa-telegram-plane"></i>
<h5 class="service__block--title">טלגרם</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
<div class="service__block" data-name="tumblr" data-order="10">
<i class="service__block--icon fab fa-tumblr"></i>
<h5 class="service__block--title">טאמבלר</h5>
<i class="service__block--arrow fas fa-chevron-circle-up"></i>
</div>
</div>
SCSS:
*
margin: 0;
padding: 0;
*,
*::before,
*::after
box-sizing: inherit;
html
box-sizing: border-box;
font-size: 62.5%; // 1rem = 10px, 10px/16px = 62.5%
body
max-height: 100vh;
font-family: 'Arimo', sans-serif;
font-weight: 400;
line-height: 1.6;
background-color: #f8f8f8;
// overflow: hidden;
overflow-x: hidden;
.content__bottom
margin-top: 3%;
width: 100vw;
height: auto;
padding: 2% 2%;
display: flex;
.service__block
cursor: pointer;
position: absolute;
width: 210px;
height: 200px;
display: flex;
flex-direction: column;
align-items: center;
padding: 3rem 5rem;
border-radius: 3.5rem;
border: 1px solid transparent;
background-color: white;
box-shadow: 5px 5px 20px rgba($color: black, $alpha: 0.05);
transition: all 0.5s;
&[data-order='0']
right: -17.5%;
display: none;
opacity: 0;
z-index: -1;
transition: none;
&[data-order='1']
right: -5.5%;
&[data-order='2']
right: 6.5%;
&[data-order='3']
right: 18.5%;
&[data-order='4']
right: 30.5%;
&[data-order='5']
right: 42.5%;
&[data-order='6']
right: 54.5%;
&[data-order='7']
right: 66.5%;
&[data-order='8']
right: 78.5%;
&[data-order='9']
right: 90.5%;
&[data-order='10']
right: 102.5%;
&[data-order='11']
right: 114.5%;
display: none;
z-index: -1;
transition: none;
&--icon
color: #adadad;
font-size: 7rem;
margin-bottom: 3rem;
transition: all 0.5s;
&--title
color: #adadad;
font-size: 2.5rem;
transition: all 0.5s;
font-weight: 400;
&--arrow
color: #4d48a8;
font-size: 3rem;
display: none;
opacity: 0;
transform: translateY(-5rem);
transition: all 0.5s;
cursor: pointer;
.service__block:hover
.service__block--icon,
.service__block--title
color: #707070;
.selected
height: 250px;
border: 1px solid #4d48a8;
.service__block--title
color: #4d48a8;
margin-bottom: 2rem;
.service__block--icon
color: #4d48a8;
.service__block--arrow
display: block;
transform: translateY(0);
opacity: 1;
&:hover
.service__block--title
color: #4d48a8;
.service__block--icon
color: #4d48a8;
JS:
const serviceList = document.querySelectorAll('.service__block');
serviceList.forEach(service =>
service.addEventListener('click', () =>
markSelectedService(service);
checkDistance(service);
moveService(checkDistance(service));
);
);
//Adds the class to the clicked service
function markSelectedService(service)
removeSelectedClass();
service.classList.add('selected');
//Removes the selected class from all the services
function removeSelectedClass()
serviceList.forEach(service =>
service.classList.remove('selected');
);
function moveServices(service)
//Check Service distance from center
checkDistance(service);
//Check if service is outside view
//Check last position of serviceList
//If service is outside view disable display
//Move service to end of the serviceList
//Enable visiblity
//Check distance from center
function checkDistance(service)
let distance = service.dataset.order - 4;
return distance;
//Check if service is outside view
//Services 1 to 9 are visible the rest are outside the view
function checkIfVisible()
serviceList.forEach(service =>
if (
parseInt(service.dataset.order) > 0 &&
parseInt(service.dataset.order) < 11
)
service.style.display = 'flex';
else
service.style.display = 'none';
);
//Move the service 1 by 1 n times
function moveService(distance)
if (distance > 0)
for (var i = 0; i < distance; i++)
serviceList.forEach(service =>
service.dataset.order = parseInt(service.dataset.order) - 1;
if (
parseInt(service.dataset.order) === 0 &&
service.dataset.name == 'instagram'
)
service.dataset.order = 11;
service.dataset.order = checkServiceListLastPosition();
else if (parseInt(service.dataset.order) === 0)
service.dataset.order = 11;
service.dataset.order = checkServiceListLastPosition() + 1;
);
else if (distance < 0)
distance = distance * -1;
for (var i = 0; i < distance; i++)
serviceList.forEach(service =>
service.dataset.order = parseInt(service.dataset.order) + 1;
);
//Check last position
function checkServiceListLastPosition()
lastPosition = 0;
serviceList.forEach(service =>
if (
parseInt(service.dataset.order) > lastPosition &&
parseInt(service.dataset.order) !== 11
)
lastPosition = parseInt(service.dataset.order);
);
console.log(lastPosition);
return lastPosition;
当前状态的代码笔: https://codepen.io/tomyshoam/pen/yLLLYyQ
【问题讨论】:
那里有很多代码要grek!问题的关键是在移动发生之前禁用正在移动的元素上的过渡 css。这将涉及添加一个类似于transition: none;
的 CSS 类
@jonny 我已经有过渡:无;在第一个和最后一个项目上禁用过渡,但它仍然弹出
【参考方案1】:
您可以在当前 .service__block 上方创建另一个 css 块,以覆盖 data-order 1 块的转换行为。
.service__block
&[data-order='1']
right: -17.5%;
display: none;
opacity: 0;
z-index: -1;
transition: none;
【讨论】:
以上是关于如何制作一个无限的 JS 轮播(无穷大问题)的主要内容,如果未能解决你的问题,请参考以下文章