How do you prevent all videos from reloading when any event occurs on the Slick carousel?
Asked Answered
A

1

8

I'm using the Slick carousel plugin to create a carousel of videos that users can add to, remove from, and filter. The problem I've got is that whenever a user does an event (add/remove/filter), all of the videos on the carousel reload, which gives a clunky feeling.

I found that the reloading can be stopped if I go into slick.js and comment out `_.$slidesCache = _.$slides;``, but that breaks the Filtering function Is there a way to prevent reloading while still preserving all functions?

JSFiddle: http://jsfiddle.net/neowot/eoov2ud1/37/

Javascript

$(document).ready(function(){
    var slideId = 0;
    var slides = [];
    $('.add-remove').slick({
        slidesToShow: 3,
        slidesToScroll: 3
    });

    var target = '<div class="videowrapper"><iframe src="https://www.youtube.com/embed/7WgYmnwO-Pw" frameborder="0" allowfullscreen></iframe></div>';

    $('.js-add-FirstClass-slide').on('click', function() {        
        $('.add-remove').slick('slickAdd','<div class="FirstClass"  slide-id="' + slideId + '"><h3><a class="sliderX">X</a>' + target + '</h3></div>');
        slides.push(slideId);
        slideId++;
    });

    $('.js-add-SecondClass-slide').on('click', function() {
        $('.add-remove').slick('slickAdd','<div class="SecondClass" slide-id="' + slideId + '"><h3><a class="sliderX">X</a>' + target + '</h3></div>');
        slides.push(slideId);
        slideId++;
    });

    var filtered = false;

    $('.ToggleFirstClass').on('click', function() {
        if (filtered === false) {
            $('.add-remove').slick('slickFilter', $('.FirstClass')); 
            filtered = true;
        } else {
            $('.add-remove').slick('slickUnfilter');
            filtered = false;
        }
    });

    $('.ToggleSecondClass').on('click', function() {
        if (filtered === false) {
            $('.add-remove').slick('slickFilter','.SecondClass'); 
            filtered = true;
        } else {
            $('.add-remove').slick('slickUnfilter');
            filtered = false;
        }
    });

    $('body').on('click', '.sliderX', function() {
        var id = parseInt($(this).closest("div").attr("slide-id"), 0);
        var index = slides.indexOf(id);
        $('.add-remove').slick('slickRemove', index);
        slides.splice(index, 1);
    });
});

slick.JS snippet

Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
    var _ = this;

    if (typeof(index) === 'boolean') {
        addBefore = index;
        index = null;
    } else if (index < 0 || (index >= _.slideCount)) {
        return false;
    }

    _.unload();

    if (typeof(index) === 'number') {
        if (index === 0 && _.$slides.length === 0) {
            $(markup).appendTo(_.$slideTrack);
        } else if (addBefore) {
            $(markup).insertBefore(_.$slides.eq(index));
        } else {
            $(markup).insertAfter(_.$slides.eq(index));
        }
        } else {
        if (addBefore === true) {
            $(markup).prependTo(_.$slideTrack);
        } else {
            $(markup).appendTo(_.$slideTrack);
        }
    }

    _.$slides = _.$slideTrack.children(this.options.slide);

    _.$slideTrack.children(this.options.slide).detach();

    _.$slideTrack.append(_.$slides);

    _.$slides.each(function(index, element) {
        $(element).attr('data-slick-index', index);
    });

    _.$slidesCache = _.$slides;

    _.reinit();
};
Antimonous answered 15/9, 2015 at 20:21 Comment(1)
Hey just letting you know dont let your bounty go to wasteSlipway
A
6

More a workaround than an answer: instead of loading the iframe, you could show the youtube thumbnail in an <img> tag.

When the user click on it, load the related iframe and autoplay the video.

For me the clunky feeling is gone: http://jsfiddle.net/eoov2ud1/40/ (but it needs some styling to show that it's a playable video, with some CSS)

Edit and actually, you can create the iframe outside of the carousel DOM, so that it becomes independent from it: http://jsfiddle.net/eoov2ud1/48/

Hence it could continue playing, even if the video is filtered/hidden/removed (with some additional JS, you can also stop the video when you detect that it was removed)

According answered 18/9, 2015 at 8:57 Comment(7)
I like this idea, but if the user clicks one of the image thumbnails to play the associated video, the problems will still take place if they try to use any of the functions afterward. In other words, once a video is loaded and playing, it will be interrupted any time the user adds/removes/filters. Any ideas on combating that? I appreciate your input greatly.Antimonous
It seems that the slick library is modifying the DOM, and that iframes will then reload. To achieve what you want, you might need to deeply change the library (it's then probably easier to write your own).According
Actually you could try to embed HTML5 YouTube video without an iframeAccording
From what I've read on different stackoverflow questions so far, it looks like embedding YouTube videos without iframes is extremely unwanted. Can you elaborate more on what changing the library would entail and what areas I should focus on? I'm pretty new to coding.Antimonous
"I'm pretty new to coding." then I wouldn't recommand you to change the library. Your first step would be to fully understand how it works, then identify where the DOM is changed, and then modify it to prevent thoses changes. Maybe you could create a feature-requestAccording
Or find another carousel library.According
Thank you! That's very clever design, and of course runs much faster. I'll be using this.Antimonous

© 2022 - 2024 — McMap. All rights reserved.