Search code examples
jquerytimeoutdelayintervalspause

Disable function for a period of time after its launched to wait animation to complete


I have a function called with mouse-wheel event that launch an animation which can be misinterpreted if it is played many times before the animation is done. I tried with setTimeout or setInterval but both keep in memory the number of events (and repeat my animation badly). The goal is to be able to call my function immediately and wait for like 2s before I can fire the event again.

It will be add on this code: JSFiddle

var scroll = 0;
$('body').bind('mousewheel', function(e) {
  if (scroll < 8) scroll++;
  else {
    scroll = 0;

  // My code...

}
});

Solution

  • You may use the :animated selector in order to test if a previous animation is already in progress:

    if ($(':animated').length > 0) {
        console.log('animation stopped because already in progress....');
        return;
    }
    

    $('body').on('mousewheel', function (e) {
        if ($(':animated').length > 0) {
            console.log('animation stopped because already in progress....');
            return;
        }
        if ($('.ecampus').css('display') == 'block') {
    
            if (e.originalEvent.wheelDelta < 0) {
    
                $('.ecampus').fadeOut();
                $('.pegasebuzz').fadeIn();
            } else {
                // TOP PAGE
            }
            return;
        }
    
        if ($('.pegasebuzz').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                $('.pegasebuzz').fadeOut();
                $('.notrecoin').fadeIn();
            } else {
                $('.pegasebuzz').fadeOut();
                $('.ecampus').fadeIn();
            }
            return;
        }
    
        if ($('.notrecoin').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                // BOTTOM PAGE
            } else {
    
                $('.notrecoin').fadeOut();
                $('.pegasebuzz').fadeIn();
            }
            return;
        }
    });
    body {
        margin: 0;
    }
    
    .ecampus {
        width: 100%;
        height: 100%;
        background: red;
        display: block;
        position: absolute;
    }
    
    .pegasebuzz {
        width: 100%;
        height: 100%;
        background: blue;
        display: none;
        position: absolute;
    }
    
    .notrecoin {
        width: 100%;
        height: 100%;
        background: yellow;
        display: none;
        position: absolute;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    
    <div class="ecampus">
        E-CAMPUS
        <br/>(Scroll down)
    </div>
    <div class="pegasebuzz">
        PEGASEBUZZ
    </div>
    <div class="notrecoin">
        NOTRE COIN
    </div>

    Another approach can be based on:

    • before starting the animation set an attribute to the body element
    • when the animation ends remove the attribute
    • the first step is: test if the attribute exists

    But this approach means you need an animation flow. In your case you have a concurrent sequence of fadeOut and fadeIn. I'd suggest you to use the complete method like in the following snippet.

    if ($('body').data('animationinprogress') !== undefined) {
    
         console.log('animation stopped because already in progress....');
    
         return;
      }
    

    $('body').on('mousewheel', function (e) {
        if ($('body').data('animationinprogress') !== undefined) {
            console.log('animation stopped because already in progress....');
            return;
        }
        if ($(':animated').length > 0) {
            console.log('animation stopped because already in progress....');
            return;
        }
        if ($('.ecampus').css('display') == 'block') {
    
            if (e.originalEvent.wheelDelta < 0) {
    
                $('body').data('animationinprogress', true);
                $('.ecampus').fadeOut(400, function() {
                    $('.pegasebuzz').fadeIn(400, function() {
                        $('body').removeData('animationinprogress');
                    });
                });
            } else {
                // TOP PAGE
            }
            return;
        }
    
        if ($('.pegasebuzz').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                $('body').data('animationinprogress', true);
                $('.pegasebuzz').fadeOut(400, function() {
                    $('.notrecoin').fadeIn(400, function() {
                        $('body').removeData('animationinprogress');
                    });
                });
            } else {
                $('body').data('animationinprogress', true);
                $('.pegasebuzz').fadeOut(400, function() {
                    $('.ecampus').fadeIn(400, function() {
                        $('body').removeData('animationinprogress');
                    });
                });
    
            }
            return;
        }
    
        if ($('.notrecoin').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                // BOTTOM PAGE
            } else {
                $('body').data('animationinprogress', true);
                $('.notrecoin').fadeOut(400, function() {
                    $('.pegasebuzz').fadeIn(400, function() {
                        $('body').removeData('animationinprogress');
                    });
                });
    
            }
            return;
        }
    });
    body {
        margin: 0;
    }
    
    .ecampus {
        width: 100%;
        height: 100%;
        background: red;
        display: block;
        position: absolute;
    }
    
    .pegasebuzz {
        width: 100%;
        height: 100%;
        background: blue;
        display: none;
        position: absolute;
    }
    
    .notrecoin {
        width: 100%;
        height: 100%;
        background: yellow;
        display: none;
        position: absolute;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    
    <div class="ecampus">
        E-CAMPUS
        <br/>(Scroll down)
    </div>
    <div class="pegasebuzz">
        PEGASEBUZZ
    </div>
    <div class="notrecoin">
        NOTRE COIN
    </div>

    Another possibility if to define your handler click handler logic in an external function with a name. Use the previous technique, for instance, and instead to define an attribute you can use .on() / .off() methods to enable / disable the event handler:

    // disable mousewheel
    $('body').off('mousewheel');
    .......
    // enable mousewheel
    $('body').on('mousewheel',mousewheelHandler);
    

    function mousewheelHandler(e) {
        if ($('.ecampus').css('display') == 'block') {
    
            if (e.originalEvent.wheelDelta < 0) {
                // disable mousewheel
                $('body').off('mousewheel');
                $('.ecampus').fadeOut(400, function() {
                    $('.pegasebuzz').fadeIn(400, function() {
                        // enable mousewheel
                        $('body').on('mousewheel',mousewheelHandler);
                    });
                });
            } else {
                // TOP PAGE
            }
            return;
        }
    
        if ($('.pegasebuzz').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                // disable mousewheel
                $('body').off('mousewheel');
                $('.pegasebuzz').fadeOut(400, function() {
                    $('.notrecoin').fadeIn(400, function() {
                        // enable mousewheel
                        $('body').on('mousewheel',mousewheelHandler);
                    });
                });
            } else {
                // disable mousewheel
                $('body').off('mousewheel');
                $('.ecampus').fadeOut(400, function() {
                    $('.notrecoin').fadeIn(400, function() {
                        // enable mousewheel
                        $('body').on('mousewheel',mousewheelHandler);
                    });
                });
            }
            return;
        }
    
        if ($('.notrecoin').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                // BOTTOM PAGE
            } else {
                // disable mousewheel
                $('body').off('mousewheel');
                $('.notrecoin').fadeOut(400, function() {
                    $('.pegasebuzz').fadeIn(400, function() {
                        // enable mousewheel
                        $('body').on('mousewheel',mousewheelHandler);
                    });
                });
    
            }
            return;
        }
    }
    
    $('body').on('mousewheel',mousewheelHandler);
    body {
        margin: 0;
    }
    
    .ecampus {
        width: 100%;
        height: 100%;
        background: red;
        display: block;
        position: absolute;
    }
    
    .pegasebuzz {
        width: 100%;
        height: 100%;
        background: blue;
        display: none;
        position: absolute;
    }
    
    .notrecoin {
        width: 100%;
        height: 100%;
        background: yellow;
        display: none;
        position: absolute;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    
    <div class="ecampus">
        E-CAMPUS
        <br/>(Scroll down)
    </div>
    <div class="pegasebuzz">
        PEGASEBUZZ
    </div>
    <div class="notrecoin">
        NOTRE COIN
    </div>

    ANSWER UPDATE

    In your last fiddle, instead, your are mixing TweenMax and jQuery animation Hence, you need a mix test:

    • the first to check if TweenMax has an active animation in progress
    • the second for an in progress jQuery animation

      if (tweenActiveAnimatoins.length > 0 || $(':animated').length > 0) {

      console.log('animation stopped because already in progress....');
      
      return;
      

      }

    var tweenVars = [];
    $(window).on('wheel', function (e) {
        var tween;
        var tweenActiveAnimatoins = tweenVars.filter(function(ele, idx) {
            return ele.isActive();
        });
        if (tweenActiveAnimatoins.length > 0 || $(':animated').length > 0) {
            console.log('animation stopped because already in progress....');
            return;
        }
        //
        // empty the array
        //
        tweenVars = [];
        if ($('.ecampus').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                $('.ecampus').fadeOut();
                $('.pegasebuzz').fadeIn();
                tween = TweenLite.from($('.pegasebuzz .corner-title'), 0.5, {
                    opacity: 0,
                    delay: 0.2
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.pegasebuzz .text-project'), 1, {
                    opacity: 0,
                    marginTop: '15px',
                    delay: 0.7
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.pegasebuzz .bottom-left img'), 1.5, {
                    opacity: 0,
                    marginTop: "-95px",
                    marginLeft: "40px",
                    delay: 1
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.pegasebuzz .top-right img'), 1, {
                    opacity: 0,
                    marginTop: "60px",
                    delay: 1.3
                });
                tweenVars.push(tween);
            } else {
                // TOP PAGE
            }
            return;
        }
        if ($('.pegasebuzz').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                $('.pegasebuzz').fadeOut();
                $('.notrecoin').fadeIn();
                tween = TweenLite.from($('.notrecoin .corner-title'), 0.5, {
                    opacity: 0,
                    delay: 0.5
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.notrecoin .text-project'), 1, {
                    opacity: 0,
                    marginTop: '15px',
                    delay: 1
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.notrecoin .top-right img'), 1, {
                    opacity: 0,
                    marginTop: "60px",
                    delay: 2
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.notrecoin .bottom-left img'), 1.5, {
                    opacity: 0,
                    marginTop: "-95px",
                    marginLeft: "40px"
                });
                tweenVars.push(tween);
            } else {
                $('.pegasebuzz').fadeOut();
                $('.ecampus').fadeIn();
            }
            return;
        }
        if ($('.notrecoin').css('display') == 'block') {
            if (e.originalEvent.wheelDelta < 0) {
                // BOTTOM PAGE
            } else {
    
                $('.notrecoin').fadeOut();
                $('.pegasebuzz').fadeIn();
                tween = TweenLite.from($('.pegasebuzz .corner-title'), 0.5, {
                    opacity: 0,
                    delay: 0.5
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.pegasebuzz .text-project'), 1, {
                    opacity: 0,
                    marginTop: '15px',
                    delay: 1
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.pegasebuzz .top-right img'), 1, {
                    opacity: 0,
                    marginTop: "60px",
                    delay: 2
                });
                tweenVars.push(tween);
                tween = TweenLite.from($('.pegasebuzz .bottom-left img'), 1.5, {
                    opacity: 0,
                    marginTop: "-95px",
                    marginLeft: "40px",
                    delay: 1.5
                });
                tweenVars.push(tween);
            }
            return;
        }
    });
    body {
        background: #141415;
        margin: 0;
        padding: 0;
        overflow: auto;
        font-family: 'Montserrat';
    }
    
    #fullPage {
        /*    box-shadow: inset 0px 0px 200px 100px rgba(0, 0, 0, 0.1);*/
        width: 100vw;
        height: 100vh;
        outline: 17px solid;
        outline-offset: -40px;
        position: fixed;
    }
    
    .gridPage {
        width: calc(100% - 80px);
        height: calc(100% - 80px);
        padding: 40px;
        position: relative;
    }
    
    .strokeGrid {
        stroke-width: 17;
        stroke: #0c0c0d;
    }
    
    .wrapper {
        width: calc(100vw - 80px);
        height: calc(100vh - 80px);
        padding: 40px;
    }
    
    .top-left {
        width: calc(50% - 9px);
        height: calc(50% - 9px);
        display: inline-block;
        vertical-align: top;
        /*    box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 255, 0.2);*/
    }
    
    .top-right {
        width: calc(50% - 9px);
        height: calc(50% - 9px);
        margin-left: 13px;
        display: inline-block;
        vertical-align: top;
        /*    box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 255, 0.2);*/
    }
    
    .bottom-left {
        width: calc(50% - 9px);
        height: calc(50% - 9px);
        display: inline-block;
        margin-top: 18px;
        vertical-align: top;
        /*    box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 255, 0.2);*/
    }
    
    .bottom-right {
        width: calc(50% - 9px);
        height: calc(50% - 9px);
        display: inline-block;
        margin-top: 18px;
        margin-left: 13px;
        vertical-align: top;
        /*    box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 255, 0.2);*/
    }
    
    /* NAVIGATION */
    
    nav {
        top: 85px;
        right: 0;
        position: absolute;
    }
    
    /* PEGASEBUZZ */
    .pegasebuzz {
        position: fixed;
        display: none;
    }
    
    .pegasebuzz .corner-title {
        font-weight: 200;
        font-size: 12pt;
        color: #2548f9;
        margin: 50px 50px 0 50px;
        position: absolute;
    }
    
    .pegasebuzz .corner-title span {
        color: #595959;
    }
    
    .pegasebuzz .text-project {
        width: 65%;
        min-width: 370px;
        font-weight: 200;
        font-size: 10pt;
        color: #b1b1b1;
        line-height: 15pt;
        padding: 120px 50px 50px 50px;
        position: relative;
    }
    
    .pegasebuzz .bottom-left img {
        max-height: 60vh;
        margin-top: -13vh;
        z-index: 40;
        position: absolute;
    }
    
    .pegasebuzz .top-right img {
        max-width: 60vw;
        height: auto;
        width: auto;
        max-height: 75vh;
        top: 8vh;
        display: block;
        margin: 0 auto;
        position: relative;
        z-index: 50;
    }
    
    /* NOTRE COIN */
    .notrecoin {
        position: fixed;
        display: none;
    }
    
    .notrecoin .corner-title {
        font-weight: 200;
        font-size: 12pt;
        color: #2548f9;
        margin: 50px 50px 0 50px;
        position: absolute;
    }
    
    .notrecoin .corner-title span {
        color: #595959;
    }
    
    .notrecoin .text-project {
        width: 65%;
        min-width: 370px;
        font-weight: 200;
        font-size: 10pt;
        color: #b1b1b1;
        line-height: 15pt;
        padding: 120px 50px 50px 50px;
        position: relative;
    }
    
    .notrecoin .bottom-left img {
        max-width: 70vw;
        max-height: 65vh;
        bottom: 4%;
        position: absolute;
        z-index: 40;
    }
    
    .notrecoin .top-right img {
        max-width: 60vw;
        height: auto;
        width: auto;
        max-height: 75vh;
        top: 8vh;
        display: block;
        margin: 0 auto;
        position: relative;
        z-index: 50;
    }
    
    /* E-CAMPUS */
    .ecampus {
        position: fixed;
        display: block;
    }
    
    .ecampus .corner-title {
        font-weight: 200;
        font-size: 12pt;
        color: #2548f9;
        margin: 50px 50px 0 50px;
        position: absolute;
    }
    
    .ecampus .corner-title span {
        color: #595959;
    }
    
    .ecampus .text-project {
        width: 65%;
        min-width: 370px;
        font-weight: 200;
        font-size: 10pt;
        color: #b1b1b1;
        line-height: 15pt;
        padding: 120px 50px 50px 50px;
        position: relative;
    }
    
    .ecampus .bottom-left img {
        max-width: 70vw;
        max-height: 65vh;
        bottom: 4%;
        position: absolute;
        z-index: 40;
    }
    
    .ecampus .top-right img {
        max-width: 60vw;
        height: auto;
        width: auto;
        max-height: 75vh;
        top: 8vh;
        display: block;
        margin: 0 auto;
        position: relative;
        z-index: 50;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.5/TweenMax.min.js"></script>
    
    <div id="fullPage">
        <svg class="gridPage" preserveAspectRatio="none">
            <line x1="0" y1="50%" x2="100%" y2="50%" class="strokeGrid"/>
            <line x1="50%" y1="100%" x2="50%" y2="0" class="strokeGrid"/>
        </svg>
    </div>
    
    <div class="wrapper ecampus">
        <div class="top-left">
    
            <div class="corner-title">E-CAMPUS<span>.01</span></div>
            <div class="text-project">
                Sed mollis vestibulum aliquam. Morbi a sapien blandit, ornare ante in, hendrerit augue. Fusce euismod lacus
                a tempor mollis. Vestibulum posuere quam tellus, eleifend auctor mauris viverra at. Sed sapien justo,
                tincidunt in ullamcorper at, suscipit sed nunc. Vivamus nibh lectus, molestie sed lacus ut, tempus ultricies
                magna <br/><br/>
                Nam cursus tortor ut accumsan interdum. Integer sed lacinia tellus. Mauris dolor libero, aliquam vulputate
                tortor ac, finibus ultricies enim. <br/><br/>
    
            </div>
        </div>
        <div class="top-right">
            <nav>
                <ul class="cf">
                    <li>
                        <a class="open-ecampus"><span class="active">01</span></a>
                        <ul class="dropdown">
                            <li><a class="open-ecampus">E-CAMPUS</a></li>
                        </ul>
                    </li>
                    <li>
                        <a class="open-pegasebuzz">02</a>
                        <ul class="dropdown">
                            <li><a class="open-pegasebuzz">PEGASEZBUZZ</a></li>
                        </ul>
                    </li>
                    <li>
                        <a class="open-notrecoin">03</a>
                        <ul class="dropdown">
                            <li><a class="open-notrecoin">NOTRE COIN</a></li>
                        </ul>
                    </li>
                </ul>
            </nav>
        </div>
        <div class="bottom-left">
        </div>
        <div class="bottom-right"></div>
    </div>
    
    <div class="wrapper pegasebuzz">
        <div class="top-left">
    
            <div class="corner-title">PEGASEBUZZ<span>.02</span></div>
            <div class="text-project">
                PegaseBuzz is an application about horses, it was very important to visualize and design something which is
                interactive. <br/><br/>
                Créons un support qui vous ressemble, en vous apportant une présence en ligne, juste et pertinente, et
                surfez sur les vagues du web avec grâce et aisance. <br/><br/>
                Nous imaginons, pour vous, des supports visuels et interactifs, sur le web, en papier, vidéo ou encore en
                réalité virtuelle.
            </div>
        </div>
        <div class="top-right">
            <nav>
                <ul class="cf">
                    <li class="open-ecampus">
                        <a class="open-ecampus">01</a>
                        <ul class="dropdown">
                            <li><a class="open-ecampus">E-CAMPUS</a></li>
                        </ul>
                    </li>
                    <li>
                        <a class="open-pegasebuzz"><span class="active">02</span></a>
                        <ul class="dropdown">
                            <li><a class="open-pegasebuzz">PEGASEZBUZZ</a></li>
                        </ul>
                    </li>
                    <li>
                        <a class="open-notrecoin">03</a>
                        <ul class="dropdown">
                            <li><a class="open-notrecoin">NOTRE COIN</a></li>
                        </ul>
                    </li>
                </ul>
            </nav>
            <img src="https://dummyimage.com/200x200/0011ff/0e0f00">
    
        </div>
        <div class="bottom-left">
            <img src="https://dummyimage.com/200x200/0011ff/0e0f00">
        </div>
        <div class="bottom-right"></div>
    </div>
    
    <div class="wrapper notrecoin">
        <div class="top-left">
    
            <div class="corner-title">NOTRE COIN<span>.03</span></div>
            <div class="text-project">
                Sed mollis vestibulum aliquam. Morbi a sapien blandit, ornare ante in, hendrerit augue. Fusce euismod lacus
                a tempor mollis. Vestibulum posuere quam tellus, eleifend auctor mauris viverra at. Sed sapien justo,
                tincidunt in ullamcorper at, suscipit sed nunc. Vivamus nibh lectus, molestie sed lacus ut, tempus ultricies
                magna <br/><br/>
                Nam cursus tortor ut accumsan interdum. Integer sed lacinia tellus. Mauris dolor libero, aliquam vulputate
                tortor ac, finibus ultricies enim. <br/><br/>
    
            </div>
        </div>
        <div class="top-right">
            <nav>
                <ul class="cf">
                    <li>
                        <a class="open-ecampus">01</a>
                        <ul class="dropdown">
                            <li><a class="open-ecampus">E-CAMPUS</a></li>
                        </ul>
                    </li>
                    <li>
                        <a class="open-pegasebuzz">02</a>
                        <ul class="dropdown">
                            <li><a class="open-pegasebuzz">PEGASEZBUZZ</a></li>
                        </ul>
                    </li>
                    <li>
                        <a class="open-notrecoin"><span class="active">03</span></a>
                        <ul class="dropdown">
                            <li><a class="open-notrecoin">NOTRE COIN</a></li>
                        </ul>
                    </li>
                </ul>
            </nav>
            <img src="https://dummyimage.com/200x200/0011ff/0e0f00">
    
        </div>
        <div class="bottom-left">
            <img src="https://dummyimage.com/200x200/0011ff/0e0f00">
        </div>
        <div class="bottom-right"></div>
    </div>

    As you can see in the previous snippet, there are some differences with your code:

    • use wheel event instead of mousewheel beacause deprecated
    • declare a global variable where to save all TweenMax instances
    • empty this array when no animation is in progress
    • save a TweenMax animation in the global array
    • filter the global array against the TweenMax animation

    Your updated fiddle here