malsup / cycle2

2nd gen cycling
899 stars 236 forks source link

Jumping page content when js first kicks in #599

Open smerriman opened 10 years ago

smerriman commented 10 years ago

Take any page containing a slideshow (eg http://jquery.malsup.com/cycle2/demo/basic.php), scroll to the very bottom, then hit refresh. You'll suddenly be jumped well up the page.

This is due to cycle2 hiding all slides as part of its initialisation routine (thus causing all content after it to jump up significantly), before redisplaying them (causing all content after it to jump back down again).

The solution on the FAQ page for preventing a 'flash of unstyled content' was to hide all but the first slide - but this is for before the JS has kicked in. Regardless of what you do, you get this flash/jump due to the JS kicking in.

Is there a better way of handling this? For example, hiding slides with visibility:hidden rather than display:none?

djowett commented 10 years ago

Did you try turning off Auto Initialization? http://jquery.malsup.com/cycle2/api/#auto-init

Just doing something like this after the slideshow works well for me:

<script type="text/javascript">
  $( '.cycle2-carousel' ).cycle();
</script>

I was only concerned with stopping a FOUC, but it also seems to help with the problem you're having.

Jaska commented 10 years ago

I have the same issue, and it auto initialization doesn't seem to help.

The only way to stop the jumping, or flash of unstyled content, is to use the responsive embed method for the slideshow: "height: 0; padding-top: 30% (calculated from aspect ratio)"

m-artin commented 9 years ago

I'm using the center-plugin and have stumbled upon the same issue. So my workaround is related to the center-plugin. (haven't tested it without it, yet)

1.) Implement the solution on the FAQ page for preventing a 'flash of unstyled content' (which will send you to: http://www.learningjquery.com/2008/10/1-way-to-avoid-the-flash-of-unstyled-content/)

This is the code I'm using in the head to hide the slideshow immediately with css and pure javascript:

<!-- Avoid flash of unstyled content in Slideshow -->
<style type="text/css">  .js div.cycle-slideshow { opacity: 0; }  </style>
<script type="text/javascript"> document.documentElement.className = 'js';  </script>

2.) Add this code after your embedded cycle2 scripts in order make the slideshow visible again by using a short timer.

<script>
// Delay to avoid flash of unstyled content in Slideshow 
$(document).on( 'cycle-pre-initialize', function( ) {
     setTimeout(function(){ $('div.cycle-slideshow').css('opacity','1') }, 65); 
});
</script>

Hope this helps.

smerriman commented 9 years ago

I'm still unable to find a valid solution to this. It especially causes problems when you want to link from an external page to an anchor that's below the slideshow (and near the bottom of the page). The slideshow content jumping up and down means you end up in a bizarre location (especially obvious on mobiles since you often can't even tell you're close.)

smerriman commented 9 years ago

PS - I realised it's not a case of display:none - it's when the plugin loops through the slides adding absolute positioning to each one. When it gets to the last slide they all have position absolute, and the whole slideshow has 0 height for a short period. Perhaps the sentinel slide could be kept unaltered temporarily or something similar?

smerriman commented 9 years ago

Additionally, the jumping happens after cycle-post-initialize, so I can't even use my own JS to scroll back to where it should be..

m-artin commented 9 years ago

Yes, this issue probably needs some attention. Because using a timer as a workaround isn't the best approach.

ghost commented 9 years ago

Ran into same problem, took me hours until I found this open bug. Content below slider jumps up/down during sliders init. First slide visible, others hidden by css. No auto-init. Container has 0 height for ~30 ms. Seems to be the same as in https://github.com/malsup/cycle2/issues/333

Tried many workarounds, but none is really useable on a production site.

Wanted a responsive replacement for Cycle, found and used Cycle2, docs said, it has responsive support, but well, jumps were not mentioned in docs...

borys-p commented 8 years ago

Same problem here. I had to use the following hack, maybe someone else will find it useful. Works with responsive sliders. Will ignore margins inside slider elements, but you shouldn't use them afterall. If all the slides have equal height you can make it even simpler.

$('.slideshow').on('cycle-bootstrap', function(e, opts) {
    var max = 0;

    $(this).find(opts.slides).each(function(el) {
        var h = $(this).height();

        if (h > max) {
            max = h;
        }
    });

    if (max > 0) {
        $(this).css('height', max);
    }
}).on('cycle-post-initialize', function(e, opts) {

    var that = this;
    setTimeout(function() {
        $(that).css('height', 'auto');
    }, 1000);

}).cycle({
  // options here
});