Search code examples
javascriptjqueryyoutubeslidercarousel

Carousel Slider with YouTube videos


Is it possible to use JQuery to build a youtube video slider? I'd like to display a few ones I uploaded.

Found some answers but made with specific frameworks, if it's possible I'd like to stick with something simple.

I found this code very helpful but I can't seem to make it work.

JSFiddle

$('.play-button').on('click', function () {
    $(this).hide();
    $(this).parent().fadeOut();
    $(this).parent().siblings('.slider-video')[0].play();
});

$('.slider-video').on('play', function () {
    $(this).attr('controls', '1');
});

// Additionnal code for the slider
var pos = 0,
    slides = $('.slide'),
    numOfSlides = slides.length;

function nextSlide(){
    stopCurrentVideo();
    slides.eq(pos).animate({left:'-100%'},500);
    pos = pos >= numOfSlides-1 ? 0 : ++pos;
    slides.eq(pos).css({left:'100%'}).animate({left:0},500);
}

function previousSlide(){
    stopCurrentVideo();
    slides.eq(pos).animate({left:'100%'},500);
    pos = pos == 0 ? numOfSlides-1 : --pos;
    slides.eq(pos).css({left:'-100%'}).animate({left:0},500);
}

function stopCurrentVideo(){
    $('.slider-video:eq('+pos+')').load().removeAttr('controls')
    .siblings('.overlay-content').show().find('.play-button').show();
}

$('.left').click(previousSlide);
$('.right').click(nextSlide);

Solution

  • You can achieve this with the YouTube iFrame API:

    https://developers.google.com/youtube/iframe_api_reference

    This API becomes available when you append enablejsapi=1 to the URLs of YouTube video embeds.

    In order to access the controls for stopping videos, for each video you need to access an instance of YT.Player. For each iFrame, I created an instance of YT.Player, and attached it directly to the slide object as a parameter called video.

    (Note that many developers say you shouldn't attach data directly to DOM objects, but I did so here because it allowed me to more closely match your original code.)

    YT.Player can be accessed through a special function that must be called onYouTubeIframeAPIReady, which I could only get to work if it was outside of $(document).ready.

    I can't put my solution on JSFiddle because the iFrames don't play nice, so here's my implementation on GitHub:

    http://robertakarobin.github.io/jquery-video-slider https://github.com/robertakarobin/jquery-video-slider

    Here are the relevant bits:

    HTML:

    <div class="video-slider">
        <!-- SLIDE 1 -->
        <div class="slide">
            <iframe class="video" src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2&enablejsapi=1"></iframe>
        </div>
        <!-- SLIDE 2 -->
        <div class="slide">
            <iframe class="video" src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2&enablejsapi=1"></iframe>
        </div>
        <!-- END OF SLIDES -->
        <div class="slide-arrow left"></div>
        <div class="slide-arrow right"></div>
    </div>
    

    JavaScript:

    $(document).ready(function () {
        var pos = 0,
            slides = $('.slide'),
            numOfSlides = slides.length;
    
        function nextSlide() {
            // `[]` returns a vanilla DOM object from a jQuery object/collection
            slides[pos].video.stopVideo()
            slides.eq(pos).animate({ left: '-100%' }, 500);
            pos = (pos >= numOfSlides - 1 ? 0 : ++pos);
            slides.eq(pos).css({ left: '100%' }).animate({ left: 0 }, 500);
        }
    
        function previousSlide() {
            slides[pos].video.stopVideo()
            slides.eq(pos).animate({ left: '100%' }, 500);
            pos = (pos == 0 ? numOfSlides - 1 : --pos);
            slides.eq(pos).css({ left: '-100%' }).animate({ left: 0 }, 500);
        }
    
        $('.left').click(previousSlide);
        $('.right').click(nextSlide);
    })
    
    function onYouTubeIframeAPIReady() {
        $('.slide').each(function (index, slide) {
            // Get the `.video` element inside each `.slide`
            var iframe = $(slide).find('.video')[0]
            // Create a new YT.Player from the iFrame, and store it on the `.slide` DOM object
            slide.video = new YT.Player(iframe)
        })
    }