Home > Software engineering >  react slideshow, needs to change (as don't repeat code)
react slideshow, needs to change (as don't repeat code)

Time:03-15

I've made a slideshow in react which is working perfectly, but my code is repeating itslef and I believe there is a better/shorter way to rewrite the code.

I originally wanted to loop through my varialbles, but couldn't find a solution for that so I just had to do with the 'ugly' way and repeat my code.

const frame1 = document.querySelector('.frame1')
const frame2 = document.querySelector('.frame2')
const frame3 = document.querySelector('.frame3')
const frame4 = document.querySelector('.frame4')
const frame5 = document.querySelector('.frame5')

I wanted to loop through them with:

for (let i = 0; i < 5; i  ) {
  console.log(frame[i])
}

But this gave there error: 'frame' is not defined

So I gave up and went to create a bunch of if statements and repeated mycode.

If anyone could help me and show how I could reduce my code I would appreciate it.

Here is my code:

let slideIndex = 1;

function showSlides(n) {
  const frame1 = document.querySelector('.frame1')
  const frame2 = document.querySelector('.frame2')
  const frame3 = document.querySelector('.frame3')
  const frame4 = document.querySelector('.frame4')
  const frame5 = document.querySelector('.frame5')

    if (n > 5) {
        slideIndex = 1;
    }
    if (n < 1) {
        slideIndex = 5;
    }

  if (frame1) {
    if (frame1 && frame1.classList.contains(`frame${slideIndex}`)) {
      frame1.classList.remove('hide')
    } else {
      frame1.classList.add('hide')
    }
  }

  if (frame2) {
    if (frame2 && frame2.classList.contains(`frame${slideIndex}`)) {
      frame2.classList.remove('hide')
    } else {
      frame2.classList.add('hide')
    }
  }

  if (frame3) {
    if (frame3 && frame3.classList.contains(`frame${slideIndex}`)) {
      frame3.classList.remove('hide')
    } else {
      frame3.classList.add('hide')
    }
  }
  
  if (frame4) {
    if (frame4 && frame4.classList.contains(`frame${slideIndex}`)) {
      frame4.classList.remove('hide')
    } else {
      frame4.classList.add('hide')
    }
  }

  if (frame5) {
    if (frame5 && frame5.classList.contains(`frame${slideIndex}`)) {
      frame5.classList.remove('hide')
    } else {
      frame5.classList.add('hide')
    }
  }
  
}

function handleSlides(e) {
  if (e.target.className === 'prev') {
    showSlides(slideIndex -= 1, e.target);
  }
  if (e.target.className === 'next') {
    showSlides(slideIndex  = 1, e.target);
  }
}
const Slideshow = () => {
  return (
    <div>
      <a className="prev" style={{padding: '5px'}} onClick={(e) => handleSlides(e)}> &#10094;</a>
          <div className="frame1" id='frame1'>
            <img src="/frames/picture-01.png" />
          </div>

          <div className="frame2 hide" id='frame2'>
            <img src="/frames/picture-02.png" />
          </div>

          <div className="frame3 hide" id='frame3'>
            <img src="/frames/picture-03.png" />
          </div>

          <div className="frame4 hide" id='frame4'>
            <img src="/frames/picture-04.png" />
          </div>

          <div className="frame5 hide" id='frame5'>
            <img src="/frames/picture-05.png" />
          </div>
          <a className="next" style={{padding: '5px'}} onClick={(e) => handleSlides(e)}>&#10095;</a>
    </div>
  )
}

CodePudding user response:

Here is what you're looking for:

function generateFrames(n) {
  const frames = [];

  for (let i = 1; i <= n; i  ) {
    frames.push(document.querySelector(`.frame${i}`));
  }

  return frames;
}

Which can then be reused as:

let slideIndex = 1;

function showSlides(n) {
  const frames = generateFrames(n);

  if (n > 5) {
    slideIndex = 1;
  }
  if (n < 1) {
    slideIndex = 5;
  }

  for (let i = 0; i < frames.length; i  ) {
    const frame = frames[i];
    
    if (frame) {
      if (frame.classList.contains(`frame${slideIndex}`)) {
        frame.classList.remove("hide");
      } else {
        frame.classList.add("hide");
      }
    }
  }
}

And in your component as:

const Slideshow = ({ frames }) => (
  <div>
    <a
      className="prev"
      style={{ padding: "5px" }}
      onClick={handleSlides}
    >
      &#10094;
    </a>

    {frames.map((frame, i) => (
      <div key={frame} className={`frame${i}`} id={`frame${i}`}>
        <img src={`/frames/picture-0${i}.png`} />
      </div>
    ))}

    <a
      className="next"
      style={{ padding: "5px" }}
      onClick={handleSlides}
    >
      &#10095;
    </a>
  </div>
);
  • Related