简体   繁体   中英

Carousel only works one time

I made code for a carousel component using "element.scrollIntoView({inline:center, behavior: smooth})". But instead of navigating horizontally through the carousel, it only works the first time, and centers vertically instead.

The strange thing is that if I go to the top of the page, and press the left or right button, it scrolls down and scrolls horizontally, then it starts working again... I don't understand what is happening.

TSX FILE:

import React, { useEffect, useState } from 'react'
import './styles.css'

export function Carousel() {

  const [currentItem, setCurrentItem] = useState(0)

  function clickArrowLeft() {
    const items = document.querySelectorAll('.items')
    const maxItems = items.length
    
    if(currentItem == 0) {
      setCurrentItem(maxItems - 1)
    }else {
    setCurrentItem(currentItem - 1)
  }
  console.log(currentItem)
}
function clickArrowRight() {
  const items = document.querySelectorAll('.items')
  const maxItems = items.length
  
  if(currentItem == maxItems - 1) {
    setCurrentItem(0)
  }else{
    setCurrentItem(currentItem + 1)
    }
    console.log(currentItem)
  }

  useEffect(()=>{
    
      const items = document.querySelectorAll('.items')
      items.forEach(item => {
        item.classList.remove('current-item')
      })
      items[currentItem].scrollIntoView({
        inline: 'center',
        behavior: 'smooth'
      })
      items[currentItem].classList.add('current-item')
    
  }, [currentItem])
  
  return (
    <div className='Carousel-container'>
      <button onClick={clickArrowLeft} className='control'>{'<'}</button>
        <div id='contain-carousel' className='wrapper'>
            <ul>
                <img className='items current-item' src='https://picsum.photos/seed/1/800/400' />
                <img className='items' src='https://picsum.photos/seed/2/800/400' />
                <img className='items' src='https://picsum.photos/seed/3/800/400' />
                <img className='items' src='https://picsum.photos/seed/4/800/400' />
                <img className='items' src='https://picsum.photos/seed/5/800/400' />
                <img className='items' src='https://picsum.photos/seed/6/800/400' />
                <img className='items' src='https://picsum.photos/seed/7/800/400' />
                <img className='items' src='https://picsum.photos/seed/8/800/400' />
                <img className='items' src='https://picsum.photos/seed/9/800/400' />
                <img className='items' src='https://picsum.photos/seed/10/800/400' />
            </ul>
        </div>
      <button onClick={clickArrowRight} className='control'>{'>'}</button>
    </div>
  )
}

CSS FILE:

.Carousel-container{
    @apply
    flex
    p-4
    m-auto
    gap-2
}

.wrapper{
    @apply
    overflow-x-auto
}

ul {
    @apply
    flex
    flex-nowrap
    gap-2
}

.items{
    @apply
    opacity-10
}

.current-item {
    @apply
    opacity-100
}

The scrollIntoView scrolls vertically, and the inline: 'center' is the one that should handle the horizontal, so no surprise there.

I cannot tell you more before seeing your CSS file.

Could you achieve what you want just by setting display: none to all items that do not have current-item class? This way you do not need to use scrollIntoView at all.

On a side note, instead of creating useEffect to detect when currentItem changes, you should have this as a separate function and call it from clickArrowRight and clickArrowLeft . This way you would avoid it being called when your component first loads (unless you want that).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM