Search code examples
javascripthtmljquerycsscarousel

How to add video inside the carousel


I have created a carousel, with dummy images. But when I am trying to embed video in it, it goes blank and throws no error at all. How can I add the video link inside the carousel so that on click of it, it gets opened up in an iframe. Attaching the screenshot of the same.

I tried replacing the img tag with video tag and created separate div too but that also seem to be not working

const galleryContainer = document.querySelector('.gallery-container');
const galleryControlsContainer = document.querySelector('.gallery-controls');
const galleryControls = ['previous', 'next'];
const galleryItems = document.querySelectorAll('.gallery-item');

class Carousel {
  constructor(container, items, controls) {
    this.carouselContainer = container;
    this.carouselControls = controls;
    this.carouselArray = [...items];
  }
  // Update css classes for gallery
  updateGallery() {
    this.carouselArray.forEach(el => {
      el.classList.remove('gallery-item-1');
      el.classList.remove('gallery-item-2');
      el.classList.remove('gallery-item-3');
      el.classList.remove('gallery-item-4');
      el.classList.remove('gallery-item-5');
    });

    this.carouselArray.slice(0, 5).forEach((el, i) => {
      el.classList.add(`gallery-item-${i + 1}`);
    });
  }

  // Update the current order of the carouselArray and gallery
  setCurrentState(direction) {

    if (direction.className == 'gallery-controls-previous') {
      this.carouselArray.unshift(this.carouselArray.pop());
    } else {
      this.carouselArray.push(this.carouselArray.shift());
    }

    this.updateGallery();
  }

  setControls() {
    this.carouselControls.forEach(control => {
      galleryControlsContainer.appendChild(document.createElement('button')).className = `gallery-controls-${control}`;

      document.querySelector(`.gallery-controls-${control}`).innerText = control;
    });
  }

  useControls() {
    const triggers = [...galleryControlsContainer.childNodes];

    triggers.forEach(control => {
      control.addEventListener('click', e => {
        e.preventDefault();

        if (control.className == 'gallery-controls-add') {
          const newItem = document.createElement('img');
          const latestItem = this.carouselArray.length;
          const latestIndex = this.carouselArray.findIndex(item => item.getAttribute('data-index') == this.carouselArray.length) + 1;

          this.carouselArray.splice(latestIndex, 0, newItem);
          document.querySelector(`[data-index="${latestItem}"]`).after(newItem);
          this.updateGallery();

        } else {
          this.setCurrentState(control);
        }

      });
    });
  }
}

function callfunc() {
  console.log("this func is being caled")
}
const exampleCarousel = new Carousel(galleryContainer, galleryItems, galleryControls);

exampleCarousel.setControls();
// exampleCarousel.setNav();
exampleCarousel.useControls();
.gallery {
  width: 100%;
}

.gallery-container {
  align-items: center;
  display: flex;
  height: 400px;
  margin: 0 auto;
  max-width: 1000px;
  position: relative;
}

.gallery-item {
  height: 150px;
  opacity: 0;
  position: absolute;
  transition: all 0.3s ease-in-out;
  width: 150px;
  z-index: 0;
}

.gallery-item-1 {
  left: 15%;
  opacity: .4;
  transform: translateX(-50%);
}

.gallery-item-2,
.gallery-item-4 {
  height: 200px;
  opacity: 1;
  width: 200px;
  z-index: 1;
}

.gallery-item-2 {
  left: 30%;
  transform: translateX(-50%);
}

.gallery-item-3 {
  box-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1);
  height: 300px;
  opacity: 1;
  left: 50%;
  transform: translateX(-50%);
  width: 300px;
  z-index: 2;
}

.gallery-item-4 {
  left: 70%;
  transform: translateX(-50%);
}

.gallery-item-5 {
  left: 85%;
  opacity: .4;
  transform: translateX(-50%);
}

.gallery-controls {
  display: flex;
  justify-content: center;
  margin: 30px 0;
}

.gallery-controls button {
  background-color: transparent;
  border: 0;
  cursor: pointer;
  font-size: 16px;
  margin: 0 20px;
  padding: 0 12px;
  text-transform: capitalize;
}

.gallery-controls button:focus {
  outline: none;
}

.gallery-controls-previous {
  position: relative;
}

.gallery-controls-previous::before {
  border: solid #000;
  border-width: 0 2px 2px 0;
  content: '';
  display: inline-block;
  height: 4px;
  left: -10px;
  padding: 2px;
  position: absolute;
  top: 0;
  transform: rotate(135deg) translateY(-50%);
  transition: left 0.15s ease-in-out;
  width: 4px;
}

.gallery-controls-previous:hover::before {
  left: -18px;
}

.gallery-controls-next {
  position: relative;
}

.gallery-controls-next::before {
  border: solid #000;
  border-width: 0 2px 2px 0;
  content: '';
  display: inline-block;
  height: 4px;
  padding: 2px;
  position: absolute;
  right: -10px;
  top: 50%;
  transform: rotate(-45deg) translateY(-50%);
  transition: right 0.15s ease-in-out;
  width: 4px;
}

.gallery-controls-next:hover::before {
  right: -18px;
}

.gallery-nav {
  bottom: -15px;
  display: flex;
  justify-content: center;
  list-style: none;
  padding: 0;
  position: absolute;
  width: 100%;
}

.gallery-nav li {
  background: #ccc;
  border-radius: 50%;
  height: 10px;
  margin: 0 16px;
  width: 10px;
}

.gallery-nav li.gallery-item-selected {
  background: #555;
}
<div class="gallery">
  <div class="gallery-container">
    <img class="gallery-item gallery-item-1" onclick="callfunc()" src="http://fakeimg.pl/300/" data-index="1">
    <img class="gallery-item gallery-item-2" src="http://fakeimg.pl/300/" data-index="2">
    <img class="gallery-item gallery-item-3" src="http://fakeimg.pl/300/" data-index="3">
    <img class="gallery-item gallery-item-4" src="http://fakeimg.pl/300/" data-index="4">
    <img class="gallery-item gallery-item-5" src="http://fakeimg.pl/300/" data-index="5">
  </div>
  <div class="gallery-controls"></div>
</div>


Solution

  • You can just add the video as a gallery item.

    If you want an image that shows the video in a modal on click, you can set a data attribute with the video url and on click send it to a hidden modal and show it.

    const galleryContainer = document.querySelector('.gallery-container');
    const galleryControlsContainer = document.querySelector('.gallery-controls');
    const galleryControls = ['previous', 'next'];
    const galleryItems = document.querySelectorAll('.gallery-item');
    
    class Carousel {
      constructor(container, items, controls) {
        this.carouselContainer = container;
        this.carouselControls = controls;
        this.carouselArray = [...items];
      }
      // Update css classes for gallery
      updateGallery() {
        this.carouselArray.forEach(el => {
          el.classList.remove('gallery-item-1');
          el.classList.remove('gallery-item-2');
          el.classList.remove('gallery-item-3');
          el.classList.remove('gallery-item-4');
          el.classList.remove('gallery-item-5');
        });
    
        this.carouselArray.slice(0, 5).forEach((el, i) => {
          el.classList.add(`gallery-item-${i + 1}`);
        });
      }
    
      // Update the current order of the carouselArray and gallery
      setCurrentState(direction) {
    
        if (direction.className == 'gallery-controls-previous') {
          this.carouselArray.unshift(this.carouselArray.pop());
        } else {
          this.carouselArray.push(this.carouselArray.shift());
        }
    
        this.updateGallery();
      }
    
      setControls() {
        this.carouselControls.forEach(control => {
          galleryControlsContainer.appendChild(document.createElement('button')).className = `gallery-controls-${control}`;
    
          document.querySelector(`.gallery-controls-${control}`).innerText = control;
        });
      }
    
      useControls() {
        const triggers = [...galleryControlsContainer.childNodes];
    
        triggers.forEach(control => {
          control.addEventListener('click', e => {
            e.preventDefault();
    
            if (control.className == 'gallery-controls-add') {
              const newItem = document.createElement('img');
              const latestItem = this.carouselArray.length;
              const latestIndex = this.carouselArray.findIndex(item => item.getAttribute('data-index') == this.carouselArray.length) + 1;
    
              this.carouselArray.splice(latestIndex, 0, newItem);
              document.querySelector(`[data-index="${latestItem}"]`).after(newItem);
              this.updateGallery();
    
            } else {
              this.setCurrentState(control);
            }
    
          });
        });
      }
    }
    
    function callfunc() {
      console.log("this func is being caled")
    }
    const exampleCarousel = new Carousel(galleryContainer, galleryItems, galleryControls);
    
    exampleCarousel.setControls();
    // exampleCarousel.setNav();
    exampleCarousel.useControls();
    .gallery {
      width: 100%;
    }
    
    .gallery-container {
      align-items: center;
      display: flex;
      height: 400px;
      margin: 0 auto;
      max-width: 1000px;
      position: relative;
    }
    
    .gallery-item {
      height: 150px;
      opacity: 0;
      position: absolute;
      transition: all 0.3s ease-in-out;
      width: 150px;
      z-index: 0;
    }
    
    .gallery-item-1 {
      left: 15%;
      opacity: .4;
      transform: translateX(-50%);
    }
    
    .gallery-item-2,
    .gallery-item-4 {
      height: 200px;
      opacity: 1;
      width: 200px;
      z-index: 1;
    }
    
    .gallery-item-2 {
      left: 30%;
      transform: translateX(-50%);
    }
    
    .gallery-item-3 {
      box-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1);
      height: 300px;
      opacity: 1;
      left: 50%;
      transform: translateX(-50%);
      width: 300px;
      z-index: 2;
    }
    
    .gallery-item-4 {
      left: 70%;
      transform: translateX(-50%);
    }
    
    .gallery-item-5 {
      left: 85%;
      opacity: .4;
      transform: translateX(-50%);
    }
    
    .gallery-controls {
      display: flex;
      justify-content: center;
      margin: 30px 0;
    }
    
    .gallery-controls button {
      background-color: transparent;
      border: 0;
      cursor: pointer;
      font-size: 16px;
      margin: 0 20px;
      padding: 0 12px;
      text-transform: capitalize;
    }
    
    .gallery-controls button:focus {
      outline: none;
    }
    
    .gallery-controls-previous {
      position: relative;
    }
    
    .gallery-controls-previous::before {
      border: solid #000;
      border-width: 0 2px 2px 0;
      content: '';
      display: inline-block;
      height: 4px;
      left: -10px;
      padding: 2px;
      position: absolute;
      top: 0;
      transform: rotate(135deg) translateY(-50%);
      transition: left 0.15s ease-in-out;
      width: 4px;
    }
    
    .gallery-controls-previous:hover::before {
      left: -18px;
    }
    
    .gallery-controls-next {
      position: relative;
    }
    
    .gallery-controls-next::before {
      border: solid #000;
      border-width: 0 2px 2px 0;
      content: '';
      display: inline-block;
      height: 4px;
      padding: 2px;
      position: absolute;
      right: -10px;
      top: 50%;
      transform: rotate(-45deg) translateY(-50%);
      transition: right 0.15s ease-in-out;
      width: 4px;
    }
    
    .gallery-controls-next:hover::before {
      right: -18px;
    }
    
    .gallery-nav {
      bottom: -15px;
      display: flex;
      justify-content: center;
      list-style: none;
      padding: 0;
      position: absolute;
      width: 100%;
    }
    
    .gallery-nav li {
      background: #ccc;
      border-radius: 50%;
      height: 10px;
      margin: 0 16px;
      width: 10px;
    }
    
    .gallery-nav li.gallery-item-selected {
      background: #555;
    }
    <div class="gallery">
      <div class="gallery-container">
        <img class="gallery-item gallery-item-1" onclick="callfunc()" src="http://fakeimg.pl/300/" data-index="1">
        <video class="gallery-item gallery-item-2" data-index="2" width="320" height="240" controls>
        <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4">
        <source src="movie.ogg" type="video/ogg">
      Your browser does not support the video tag.
      </video>
        <img class="gallery-item gallery-item-3" src="http://fakeimg.pl/300/" data-index="3">
        <img class="gallery-item gallery-item-4" src="http://fakeimg.pl/300/" data-index="4">
        <img class="gallery-item gallery-item-5" src="http://fakeimg.pl/300/" data-index="5">
      </div>
      <div class="gallery-controls"></div>
    </div>