Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
86 views
in Technique[技术] by (71.8m points)

javascript - Remove slide delay vanilla js

I've got some section with infinite carousel using vanilla js. My logic is based on using justify-content:flex-end for previous slide and justify-content:flex-start for next one. My carousel has default justify-content:flex-start and it works fine when slides to next, but there is some render delay if I'm using slide to prev. It's because of using justify-content:flex-end for prev, but how to get rid of delay? This is my code

const slider = document.querySelector('.slider')
const carousel = document.querySelector('.carousel')
const prev = document.querySelector('.prev')
const next = document.querySelector('.next')

let direction

prev.addEventListener('click', () => {
    if (direction === -1) {
        slider.appendChild(slider.lastElementChild)
        direction = 1
    }
    direction = 1
    carousel.style.justifyContent = 'flex-end'
    slider.style.transform = 'translate(20%)'
})

next.addEventListener('click', () => {
    direction = -1
    carousel.style.justifyContent = 'flex-start'
    slider.style.transform = 'translate(-20%)'
})

slider.addEventListener('transitionend', () => {
    if (direction === -1) {
        slider.appendChild(slider.firstElementChild)
    } else if (direction === 1) {
        slider.prepend(slider.lastElementChild)
    }

    slider.style.transition = 'none'
    slider.style.transform = 'translate(0)'
    setTimeout(() => {
        slider.style.transition = 'transform 0.5s'
    })
})
.section {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 80px 0;
  background-color: green;
  position: relative;
}

.carousel {
  display: flex;
  width: 70%;
  height: 100%;
  justify-content: flex-start;
  position: relative;
  overflow: hidden;
}

.slider {
  display: flex;
  width: 100%;
  height: 100%;
  transition: all 0.5s;
}

.item {
  display: flex;
  width: 20%;
  flex: 1;
  flex-shrink: 0;
  flex-basis: 20%;
  height: 70px;
}

.prev,
.next {
  position: absolute;
  height: 70px;
  width: 70px;
  border-radius: 50%;
  border: 1px solid green;
  cursor: pointer;
  z-index: 3;
}

.prev {
  left: 20px;
}

.next {
  right: 20px;
}
<section class="section">
    <div class="prev">Prev</div>
    <div class="next">Next</div>
    <div class="carousel">
        <div class="slider">
            <div class="item"> Item 1</div>
            <div class="item"> Item 2</div>
            <div class="item"> Item 3</div>
            <div class="item"> Item 4</div>
            <div class="item"> Item 5</div>
            <div class="item"> Item 1</div>
            <div class="item"> Item 2</div>
            <div class="item"> Item 3</div>
            <div class="item"> Item 4</div>
            <div class="item"> Item 5</div>
        </div>
    </div>
</section>
question from:https://stackoverflow.com/questions/65919228/remove-slide-delay-vanilla-js

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Not sure if this is the best approach. Your code is appending (and prepending) elements after the slider has transitioned. Because of the overflow:hidden you don't notice it happen when it appends to the end of the slider but you notice when it prepends to the start which is why you see it render after the translation. So you could move the slider 20% to the left so you don't see when the element is prepended and not change most of your code.

const slider = document.querySelector('.slider')
const carousel = document.querySelector('.carousel')
const prev = document.querySelector('.prev')
const next = document.querySelector('.next')

let direction

prev.addEventListener('click', () => {
    if (direction === -1) {
        slider.appendChild(slider.lastElementChild)
        direction = 1
    }
    direction = 1
    // removed - carousel.style.justifyContent = 'flex-end'
    slider.style.transform = 'translate(20%)'
})

next.addEventListener('click', () => {
    direction = -1
    // removed - carousel.style.justifyContent = 'flex-start'
    slider.style.transform = 'translate(-20%)'
})

slider.addEventListener('transitionend', () => {
    if (direction === -1) {
        slider.appendChild(slider.firstElementChild)
    } else if (direction === 1) {
        slider.prepend(slider.lastElementChild)
    }

    slider.style.transition = 'none'
    slider.style.transform = 'translate(0)'
    setTimeout(() => {
        slider.style.transition = 'transform 0.5s'
    })
})
.section {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 80px 0;
  background-color: green;
  position: relative;
}

.carousel {
  display: flex;
  width: 70%;
  height: 100%;
  justify-content: flex-start;
  position: relative;
  overflow: hidden;
}

.slider {
  display: flex;
  width: 100%;
  height: 100%;
  transition: all 0.5s;
  /* Only change */ margin-left: -20%;
}

.item {
  display: flex;
  width: 20%;
  flex: 1;
  flex-shrink: 0;
  flex-basis: 20%;
  height: 70px;
}

.prev,
.next {
  position: absolute;
  height: 70px;
  width: 70px;
  border-radius: 50%;
  border: 1px solid green;
  cursor: pointer;
  z-index: 3;
}

.prev {
  left: 20px;
}

.next {
  right: 20px;
}
<section class="section">
    <div class="prev">Prev</div>
    <div class="next">Next</div>
    <div class="carousel">
        <div class="slider">
            <div class="item"> Item 1</div>
            <div class="item"> Item 2</div>
            <div class="item"> Item 3</div>
            <div class="item"> Item 4</div>
            <div class="item"> Item 5</div>
            <div class="item"> Item 6</div>
            <div class="item"> Item 7</div>
            <div class="item"> Item 9</div>
            <div class="item"> Item 0</div>
        </div>
    </div>
</section>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...