Pause Scrolling to Next 'Slide' till all A

2019-04-28 06:26发布

问题:

I am creating a 'limited' visual builder for Skrollr sliders. It allows the user to build sliders that consist of slides (html section tags) that sit one below each other on the page, each slide contains many html elements that have Skrollr data attributes/animations (keyframes?) applied to them.

Is there a way to pause that slides (advancement to the next slide) until all its inner elements have completed their animations?

I am aware of the example pausing.html that demonstrates kindof what I need but these 'slides' are fixed which could cause problems for my users. The sliders will be chucked into WordPress website themes where most elements are not fixed.

Because the slide contents are so dynamic and unpredictable its hard to know how long to lock scrolling? Hopefully its possible to do this?

Example of my dilemma:

.... Some regular WordPress page content (Navbar, Header maybe posts, etc.)

<div id="skrollr-body">

    // Pause this slides scrolling till all child elements have completed their animations
    // Slide child elements will ALWAYS have relative animations (data-100-top="..." NOT data-100="...")
    <section id="slide-1" class="slide">

        <p data-center="opacity: 1;" data-top="opacity: 0;">Some awesomeness</p>

        <img data--100-center="transform: translate(-100%,0);" data-top="transform: translate(0,0);"  src="..."/>

        ... lots of other elements

    </section>

    <section id="slide-2" class="slide">
        ...
    </section>

    <section id="slide-3" class="slide">
        ...
    </section>

</div>

.... Some regular WordPress page content (Footer, maybe posts, etc.)

回答1:

Please refer to the following resources:

  • Skrollr
  • Skrollr Menu
  • How to programmatically disable page scrolling with jQuery
  • Skrollr Parallax Tutorial
  • jQuery .promise() and $.when

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Demo - Simple parallax scrolling tutorial</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
        <link rel="stylesheet" href="css/normalize.css">
        <link rel="stylesheet" href="css/main.css">

        <style>
            body {
                font-family: 'Open Sans', sans-serif;
            }
      .on { cursor: pointer; pointer-events: auto; }
      .off { cursor: not-allowed; pointer-events: none; }

        </style>
    </head>
    <body class="loading">

        <div id="preload">
            <img src="img/bcg_slide-1.jpg">
            <img src="img/bcg_slide-2.jpg">
            <img src="img/bcg_slide-3.jpg">
            <img src="img/bcg_slide-4.jpg">
        </div>

        <main>

            <section id="slide-1" class="homeSlide">
                <div class="bcg">
                    <div class="hsContainer">
              <button id="test">TEST</button>
                        <div class="hsContent">
              <span class="launch"><a class="off" href="#slide-2"><hr/>
                            <h2>Simple parallax scrolling is...</h2></a></span>
                        </div>
                    </div>
                </div>
            </section>

            <section id="slide-2" class="homeSlide">
                <div class="bcg">
                    <div class="hsContainer">
                        <div class="hsContent">
                <span class="launch"><a class="off" href="#slide-3"><hr/>
                            <h2>great for story telling websites.</h2></a></span>
                        </div>
                    </div>
                </div>
            </section>

            <section id="slide-3" class="homeSlide">
                <div class="bcg">
                    <div class="hsContainer">
                        <div class="hsContent">
                <span class="launch"><a class="off" href="#slide-4"><hr/>
                            <h2>Now go and create your own story</h2></a></span>
                        </div>
                    </div>

                </div>
            </section>

            <section id="slide-4" class="homeSlide">
                <div class="bcg">

                    <div class="hsContainer">
                        <div class="hsContent">
               <span class="launch"><a class="off" href="#slide-1"><hr/>
                            <h2>and share mine.</h2></a></span>
                        </div>
                    </div>

                </div>
            </section>

        </main>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')</script>
        <script src="js/imagesloaded.js"></script>
        <script src="js/skrollr.js"></script>
        <script src="js/skrollr.menu.min.js"></script>
        <script src="js/_main.js"></script>
                <script>
                $(function() {

                    /* Scrolling and jump links are disabled initially */
                    $('html, body').css({
                    'overflow': 'hidden',
                    'height': '100%'
                    });
                    var lnk = document.querySelector('a');
                    $(lnk).removeAttr('href');
                    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

                    /* This test button (located upper left corner), is to simulate the beginning and completion of any animation */
                    /* var effect is the animation test, which can be swapped out for your real animations. */
                    /* From here you can store and initiate animations and manipulate the DOM, I'm not sure how you implement content dynamically (no details provided), but with all interaction paused as it is and a promise to back you up, you should have no problems. */ 
                    $('#test').on('click', function(event) {
                    var effect = function() {
                    return $( "a" ).fadeOut( 800 ).delay( 1200 ).fadeIn( 1600 );
                    };
                    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

                    /* This is a .promise using a $.when statement which restores scrolling and links AFTER the animation is completed. */
                    $.when( effect() ).done(function() {
                    $("a").toggleClass('on off');
                        $('html, body').css({
                            'overflow': 'auto',
                            'height': 'auto'
                        });
                        $(lnk).attr('href', '#slide-2');
                });
                    });
                });
                </script>
    </body>
</html>

I forgot there's additional modifications to _main.js, they annotated with a ✓:

_main.js

( function( $ ) {

    // Setup variables
    $window = $(window);
    $slide = $('.homeSlide');
    $body = $('body');

    //FadeIn all sections   
    $body.imagesLoaded( function() {
        setTimeout(function() {

              // Resize sections
              adjustWindow();

              // Fade in sections
              $body.removeClass('loading').addClass('loaded');

        }, 800);
    });

    function adjustWindow(){

        // Init Skrollr
        // Added Skrollr and Skrollr Menu init ✓

        var s = skrollr.init(); 
        skrollr.menu.init(s, {
            animate: true
        });

        // Get window size
        winH = $window.height();

        // Keep minimum height 550
        if(winH <= 550) {
            winH = 550;
        } 

        // Resize our slides
        $slide.height(winH);

        // Refresh Skrollr after resizing our sections
        // Added the Skrollr refresh ✓
        s.refresh();

    }

} )( jQuery );


回答2:

Disable the next button till the animation complete, you can enable after CSS animation complete. Here is an article explaining how to track CSS animation callback.