Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
88 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 Answer

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...