Clearing a responsive jQuery Cycle
Asked Answered
J

4

8

I've created a responsive image slider using jQuery cycle.

The following setup I have used works fine, apart from the containing .cycle div is not cleared correctly, making any content after it sit underneath it.

This is due to the fact the div is relative and its children are absolute.

     $('.cycle').cycle({
        slideResize: true,
        containerResize: false,
        fit: 1,
        width: "fit"
     });

My question is , how can I clear the responsive .cycle div without having a fixed height or using some event heavy JavaScript?

Here is my code on jsfiddle: http://jsfiddle.net/blowsie/HuNfz/19/


Update:

I wrote some code to fix the height of the cycle, which works as expected (although it can bug out sometimes), but its event heavy and not very slick.

Id love to see can be done in pure CSS or a change in the cycle setup.

http://jsfiddle.net/blowsie/HuNfz/22/

Jacquetta answered 20/9, 2012 at 8:39 Comment(4)
I changed the containerResize property to true and then it worked, but then it's not responsive anymore..maybe it helps..Diverse
nope, it needs to be responsive! Thanks thoJacquetta
Not sure if you're open to another piece of tech, but I love and use Wilto's Dynamic Carousel.Masbate
@JeffreyLo Thanks but this doesn't quite cut it, I need the fade effect and other options that it doesn't have.Jacquetta
S
9

Cycle is not very responsive friendly. But Cycle2 definitely is. Check it out here: http://jquery.malsup.com/cycle2/

Simpatico answered 26/9, 2012 at 13:59 Comment(1)
For those curious as to the configuration to achieve this see here. jsfiddle.net/blowsie/HuNfz/49Jacquetta
G
0

Possibly adding a resize windows:

$(window).resize(function () {
    $('.cycle').height($('img:visible').height());
});
setTimeout(300, $(window).resize());

http://jsfiddle.net/HuNfz/60/

Godwin answered 9/10, 2012 at 21:41 Comment(1)
constant polling is a really bad idea other than that the approach is similar to my mock up in the question.Jacquetta
L
0

Old post, I know.

We have it working in production with cycle. Cycle2 was not and is still not an option for us. Unfortunately, it involves modifying cycle's internal data. Luckily, the fix is straightforward.

When the cycle plugin initializes, it adds two propeties cycleW and cycleH to each of your slides' DOM object with respectively the initial width and height of each slide. Cycle uses these properties to animate each slide regardless of the dimension of the window.

When the window is resized, you need to clear cycleW and cycleH manually or set them to a pre determined value.

Example (assuming your slideshow container is .slideshow):

$(".slideshow").children("div").each(function(){
    this.cycleW = $(this).width();
    this.cycleH = $(this).height();
});

We have it working very well in production.

html looks like this:

<div class="slideshow">
    <div class="slide"><img src=".." width="100%" height="auto"/></div>
    <div class="slide"><p>Copy copy copy no photo on slide </p></div>
    <div class="slide"><img src=".." width="100%" height="auto"/></div>
    <div class="slide"><p>Copy copy copy no photo on slide </p></div>
    ...
</div>

Now the window resize function. This is our version. You might need to customize this to fit your needs. Basically, we store the initial ratio for the cases we have fixed images in the slideshow. There are times we have variable height slideshows. This code addresses both situations. Then, it resets the internal cycleW and cycleH values of each slide DOM element to fit their parent container

$(window).resize(function(){
    // first time around, save original width & height for ratios and complicated preloading
    $(".slideshow").each(function(i,elt){
        var originalWidth = $(elt).data("originalWidth"); // check existence of our ratio cache
        if (typeof originalWidth == "undefined") {
            var containerWidth = $(elt).parent().first().width(); // auto scale to container width.
            var containerHeight = $(elt).parent().first().height();
            $(elt).data("originalWidth",containerWidth);
            $(elt).data("originalHeight",containerHeight);
        }
    });

    // fix slideshows to their container width
    $(".slideshow").each(function(i,elt){
        var containerWidth = $(elt).parent().first().width();
        var originalWidth = $(elt).data("originalWidth")*1;
        var originalHeight = $(elt).data("originalHeight")*1;
        var height = Math.floor(originalHeight*containerWidth/originalWidth);   // maintain original ratio
        $(elt).css("width", containerWidth+"px").css("height",height+"px"); // container actual dimensions. height might get reset again below
        $(elt).children("div").css("width", containerWidth+"px"); // reset each slide width 
                                                                 // (fails once slide moves out, because the cycle plugin will use a cached value)
        $(elt).children("div").children().css("width", containerWidth+"px"); // fix direct children (images or divs - images should have height auto).

        // recompute max height based on inside slide, not just photos.
        // some slideshows have variable height slides.
        var maxHeight = 0;
        var panelArray = $(elt).children("div");
        for (var i = 0; i < panelArray.length; i++) {
            var height = $(panelArray[i]).height();
            if (height > maxHeight) maxHeight = height;
        }
        if (maxHeight > 0) {
            $(elt).height(maxHeight);
        }

        // fix internal cycle dimension cache (cycleW and cycleH on each slide)
        $(elt).children("div").each(function(){
            this.cycleW = containerWidth;
            this.cycleH = maxHeight;
        });
    });
});
Larval answered 27/1, 2015 at 11:31 Comment(2)
Just some pointers, this code of yours is very expensive and will run too frequently. You should definitely store some of your variables higher up and debounce your function.Jacquetta
Yep, we debounce it in production :) This is a simplified example we modified for this demo, could definitely be optimized.. But the question was about clearing a cycle plugin for responsiveness, which this post explains. That being said, since you spoke of it, debouncing is not the answer to smooth UI responsiveness. It can create horrendous transitions, and tightening up the interval can defeat the purpose. Cheers and thanks for the comment :)Larval
C
-1

By default the plugin assigns position:relative to your and also to s within that it assigns position: absolute and z-index values. Which makes the slideshow be a floater/unstuck in a stack. I found 2 solutions to the issue:

  1. Add clearfix class to your and add css styles for clearfix into your stylesheet.

    .clearfix:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }

    .clearfix { display: inline-block; }

    html[xmlns] .clearfix { display: block; }

    • html .clearfix { height: 1%; }
  2. (Not very elegant) add border to your cycle class

    .cycle { border: 1px solid #f00; }

Hope one of these helps.

Cawnpore answered 26/9, 2012 at 11:12 Comment(1)
Thanks for your answer but... Neither solution works for me - Solution 1 =jsfiddle.net/blowsie/HuNfz/47 , Solution 2 = jsfiddle.net/blowsie/HuNfz/46Jacquetta

© 2022 - 2024 — McMap. All rights reserved.