JQuery - Slick Carousel and Fancybox conflict
Asked Answered
M

5

6

I have coded a system which uses the Slick Slider plugin so that I can slide horizontally from one content to another (those slides are including both pictures and text). I also added Fancybox so that I can see the pictures in those slides in fullscreen If needed.

But those two plugins kind of conflict with each other.

Everything works but if I have more than one slide, the Fancybox gallery will show me several times the same picture (it behaves like a gallery of the same picture).

It's clearly a conflict as when I get rid of the slider js file, the Fancybox works again as it should (each picture is only showed once).

And when I keep both the galleries, the strangest thing is that the gallery behavior only occurs when I add sliders, even though they don't embed anything at all, no Fancybox, no pictures, no nothing.

Here below a jsfiddle link. My code is way more complicated of course but I made it as simple as it is possible to be for the test case. Almost no styling or js besides the plugins.

You'll see that if you get rid of everything inside the ".slider2" div, it will behave just fine. If not, the first picture will display a gallery of 2 identical pictures (instead of one and it will say by default that it is showing the picture 1 of 2) while the second image will display a gallery of 3 identical images (instead of one and it will say by default that it is showing the picture 2 of 3).

Thank you for your help.

<head>

    <link rel="stylesheet" type="text/css" href="styles/jquery.fancybox.css" />
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.css"/>

    <style>
        img{width:50%;}
    </style>
</head>

<body>

    <div class="container">

        <div class="slider_block">

            <div class="slider1">

                <a data-fancybox="test1" href="https://www.lexgotham.com/test/images/im1.jpg">

                    <img alt="" src="https://www.lexgotham.com/test/images/im1.jpg" />

                </a>

            </div>

            <div class="slider2">

                <a data-fancybox="test2" href="https://www.lexgotham.com/test/images/im2.jpg">

                    <img alt="" src="https://www.lexgotham.com/test/images/im2.jpg" />

                </a>

            </div>

        </div>

    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>   

    <script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.min.js"></script>

    <script src="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>

    <script>$(document).ready(function() {$('.sliding').slick({});});</script>

</body>

Demo: http://jsfiddle.net/evsq80az/10

Mister answered 30/7, 2018 at 7:31 Comment(0)
H
3

Slick clones the slides in order to "rotate" the carousel. Which means you have more than 1 picture with the same value of data-fancybox. Which is passed on as rel value to each link with a data-fancybox value.

To disable the gallery feature, you have to not pass a rel value, so just specify the data-fancybox without a value:

<a data-fancybox href="https://www.lexgotham.com/test/images/im2.jpg">

See it working:

$(window).on('load', () => {
  $('.slider_block').slick();
});
img {
  width: 50%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.css" rel="stylesheet" />
<link href="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.min.js"></script>
<script src="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
<html>


<div class="container">
  <div class="slider_block">
    <div class="slider1">
      <a data-fancybox href="https://www.lexgotham.com/test/images/im1.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im1.jpg" />
      </a>
    </div>
    <div class="slider2">
      <a data-fancybox href="https://www.lexgotham.com/test/images/im2.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im2.jpg" />
      </a>
    </div>
  </div>
</div>

If you need the rels (gallery feature) to create custom groups of your slides, you'll have to prevent slick from cloning the slides, by disabling its infinite rotation:

 $('.slider_block').slick({
   infinite: false;
 });

$(window).on('load', () => {
  $('.slider_block').slick({infinite:false});
});
img {
  width: 50%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.css" rel="stylesheet" />
<link href="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.min.js"></script>
<script src="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
<html>


<div class="container">
  <div class="slider_block">
    <div>
      <a data-fancybox="gallery-1" href="https://www.lexgotham.com/test/images/im1.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im1.jpg" />
      </a>
    </div>
    <div>
      <a data-fancybox="gallery-1" href="https://www.lexgotham.com/test/images/im2.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im2.jpg" />
      </a>
    </div>
    <div>
      <a data-fancybox="gallery-2" href="https://www.lexgotham.com/test/images/im1.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im1.jpg" />
      </a>
    </div>
    <div>
      <a data-fancybox="gallery-2" href="https://www.lexgotham.com/test/images/im2.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im2.jpg" />
      </a>
    </div>
  </div>
</div>

P.S: [SO] doesn't let you add links to jsfiddle because the fiddle has to be in the post, not on JSfiddle. If you update your fiddle (because, maybe, you want to test the answer?) it will no longer be relevant to future users. Which means you ask for help but don't want to help others.

In short, you can link a fiddle, but it has to compliment the code in the question, not replace it.

Hillary answered 30/7, 2018 at 7:49 Comment(3)
Thank you very much for your answer. The thing is, I need the gallery feature. Here I just pasted an easy sample to easily see what's going on but these pictures will be gathered into galleries. And when they are, the first image of each gallery is showed (at least) twice. So are you saying that Fancybox and Carousel won't work together if I need the gallery feature?Mister
If you need the rel, disable the infinite rotation on slick. You can't have both. $('.slider_block').slick({infinite:false}); Pick one or the other. Updated my answer.Hillary
That's all I needed to know, thanks! Indeed, I don't need the infinite feature and now it works as expected, thank you.Mister
N
7

You have to initialize the script using selector for "real" slides and then simply add custom click event for cloned ones:

var selector = '.slick-slide:not(.slick-cloned)';

// Init fancybox, skip cloned elements
$().fancybox({
  selector : selector,
  backFocus : false,
  animationEffect : "fade"
});

// Custom click event on cloned elements, 
$(document).on('click', '.slick-cloned', function(e) {
  $(selector)
    .eq( ( $(this).attr("data-slick-index") || 0) % $(selector).length )
    .trigger("click.fb-start", { $trigger: $(this) });

  return false;
});

Demo - https://codepen.io/fancyapps/pen/jvbEgo

Nuncia answered 2/8, 2018 at 9:52 Comment(4)
Doesn't work. On the first opening, it works, but after using the slider, it shows thumbs of the clones. Also, not related to the OP, when sliding through the fancy box slides, it changes the slide in the slick slider to the image in the fancy box slide and it's a horrible jump plus it's not on the correct number with the dots (count) on slick. Something happened with it between last year and this year, didn't happen in the past.Osteopathy
That is very, very helpful and also fixed my issues.Osteopathy
Thx, works great. can be simplified as $().fancybox({selector : selector});. In my case of many slides I didn't even need the custom event.Vitamin
Genius man! ThanksMelee
H
3

Slick clones the slides in order to "rotate" the carousel. Which means you have more than 1 picture with the same value of data-fancybox. Which is passed on as rel value to each link with a data-fancybox value.

To disable the gallery feature, you have to not pass a rel value, so just specify the data-fancybox without a value:

<a data-fancybox href="https://www.lexgotham.com/test/images/im2.jpg">

See it working:

$(window).on('load', () => {
  $('.slider_block').slick();
});
img {
  width: 50%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.css" rel="stylesheet" />
<link href="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.min.js"></script>
<script src="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
<html>


<div class="container">
  <div class="slider_block">
    <div class="slider1">
      <a data-fancybox href="https://www.lexgotham.com/test/images/im1.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im1.jpg" />
      </a>
    </div>
    <div class="slider2">
      <a data-fancybox href="https://www.lexgotham.com/test/images/im2.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im2.jpg" />
      </a>
    </div>
  </div>
</div>

If you need the rels (gallery feature) to create custom groups of your slides, you'll have to prevent slick from cloning the slides, by disabling its infinite rotation:

 $('.slider_block').slick({
   infinite: false;
 });

$(window).on('load', () => {
  $('.slider_block').slick({infinite:false});
});
img {
  width: 50%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.css" rel="stylesheet" />
<link href="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.3.5/jquery.fancybox.min.js"></script>
<script src="http://cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
<html>


<div class="container">
  <div class="slider_block">
    <div>
      <a data-fancybox="gallery-1" href="https://www.lexgotham.com/test/images/im1.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im1.jpg" />
      </a>
    </div>
    <div>
      <a data-fancybox="gallery-1" href="https://www.lexgotham.com/test/images/im2.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im2.jpg" />
      </a>
    </div>
    <div>
      <a data-fancybox="gallery-2" href="https://www.lexgotham.com/test/images/im1.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im1.jpg" />
      </a>
    </div>
    <div>
      <a data-fancybox="gallery-2" href="https://www.lexgotham.com/test/images/im2.jpg">
        <img alt="" src="https://www.lexgotham.com/test/images/im2.jpg" />
      </a>
    </div>
  </div>
</div>

P.S: [SO] doesn't let you add links to jsfiddle because the fiddle has to be in the post, not on JSfiddle. If you update your fiddle (because, maybe, you want to test the answer?) it will no longer be relevant to future users. Which means you ask for help but don't want to help others.

In short, you can link a fiddle, but it has to compliment the code in the question, not replace it.

Hillary answered 30/7, 2018 at 7:49 Comment(3)
Thank you very much for your answer. The thing is, I need the gallery feature. Here I just pasted an easy sample to easily see what's going on but these pictures will be gathered into galleries. And when they are, the first image of each gallery is showed (at least) twice. So are you saying that Fancybox and Carousel won't work together if I need the gallery feature?Mister
If you need the rel, disable the infinite rotation on slick. You can't have both. $('.slider_block').slick({infinite:false}); Pick one or the other. Updated my answer.Hillary
That's all I needed to know, thanks! Indeed, I don't need the infinite feature and now it works as expected, thank you.Mister
N
1

In case anyone is looking for an EASY surefire way to not display the cloned slides in your fancybox gallery (v3). Just simply use this code:

$('[data-fancybox]:not(.slick-cloned)').fancybox();
Najera answered 23/7, 2019 at 16:55 Comment(3)
This will prevent cloned slides from having any fancybox functionality though.Celandine
That is correct, but in a gallery why would you want the cloned slides in it?Najera
It worked. this is a useful answer. why didn't anyone upvote it?Entrance
C
0

best solution for me if you are using the v3 of fancybox. use update() to recalculate the size.

   $('[data-fancybox="images"]').fancybox({

        afterLoad : function(instance, current) {
            instance.update();

        }
    });
Cristal answered 9/4, 2019 at 13:44 Comment(0)
M
0

This code helps you to solve the conflict issue of the slick slider with fancybox. Also, solve duplicate thumbnails issue in fancybox popup when slick slider infinite loop is on. Let's try the below code.

 jQuery(document).ready(function ($) {
        $('.carousel-section').each(function () {
            var selector = '.carousel-section .slick-slide:not(.slick-cloned) [data-fancybox="fancybox_view"]';
    
            $().fancybox({
                selector: selector,
                backFocus: false,
                margin: [44, 0, 22, 0],
                baseClass: 'carousel-fancybox-wrapper',
                loop: true,
                thumbs: {
                    autoStart: thumb,
                    axis: 'x'
                },
                toolbar: true,
                infobar: true,
            })
 
            $('.carousel-section').on('click', '.slick-cloned', function (e) {
                $(selector)
                    .eq(($(e.currentTarget).attr("data-slick-index") || 0) % $(selector).length)
                    .trigger("click", {
                        $trigger: $(this)
                    });
                return false;
            });
        })
        
    });
Mastodon answered 9/2, 2021 at 9:51 Comment(1)
Please explain more about how modulus and math helped isolate the problem. I get the gist is to precisely declare or exclude selectors.Carbonic

© 2022 - 2024 — McMap. All rights reserved.