使用smoothscroll.js在按键上停止锚定滚动

时间:2014-02-21 13:47:11

标签: anchor smooth-scrolling

我正在尝试使用http://cferdinandi.github.io/smooth-scroll/中的smoothscroll.js在我的网站上获得一个很好的缓动滚动效果(如下面的代码所示),它运行正常。但是,在有效的情况下使用鼠标滚轮滚动会导致页面在整个地方抖动,因为有两个动画正在发生 - 一个来自鼠标滚轮,另一个来自锚定滚动。所以我想在锚点滚动动画上禁用鼠标滚轮或在鼠标滚轮上禁用锚点滚动动画。我不知道如何改变代码来做到这一点。我很确定我应该能够在下面的代码中添加一行或两行,但我已经尝试了很多个小时而且我无法正常工作。

/* =============================================================

Smooth Scroll 3.2
Animate scrolling to anchor links, by Chris Ferdinandi.
http://gomakethings.com

Easing support contributed by Willem Liu.
https://github.com/willemliu

Easing functions forked from Gaëtan Renaudeau.
https://gist.github.com/gre/1650294

URL history support contributed by Robert Pate.
https://github.com/robertpateii

Fixed header support contributed by Arndt von Lucadou.
https://github.com/a-v-l

Infinite loop bugs in iOS and Chrome (when zoomed) by Alex Guzman.
https://github.com/alexguzman

Free to use under the MIT License.
http://gomakethings.com/mit/

* ============================================================= */

window.smoothScroll = (function (window, document, undefined) {

'use strict';

// Feature Test
if ( 'querySelector' in document && 'addEventListener' in window && Array.prototype.forEach ) {

    // SELECTORS

    var scrollToggles = document.querySelectorAll('[data-scroll]');


    // METHODS

    // Run the smooth scroll animation
    var runSmoothScroll = function (anchor, duration, easing, url) {

        // SELECTORS

        var startLocation = window.pageYOffset;

        // Get the height of a fixed header if one exists
        var scrollHeader = document.querySelector('[data-scroll-header]');
        var headerHeight = scrollHeader === null ? 0 : scrollHeader.offsetHeight;

        // Set the animation variables to 0/undefined.
        var timeLapsed = 0;
        var percentage, position;


        // METHODS

        // Calculate the easing pattern
        var easingPattern = function (type, time) {
            if ( type == 'easeInQuad' ) return time * time; // accelerating from zero velocity
            if ( type == 'easeOutQuad' ) return time * (2 - time); // decelerating to zero velocity
            if ( type == 'easeInOutQuad' ) return time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration
            if ( type == 'easeInCubic' ) return time * time * time; // accelerating from zero velocity
            if ( type == 'easeOutCubic' ) return (--time) * time * time + 1; // decelerating to zero velocity
            if ( type == 'easeInOutCubic' ) return time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration
            if ( type == 'easeInQuart' ) return time * time * time * time; // accelerating from zero velocity
            if ( type == 'easeOutQuart' ) return 1 - (--time) * time * time * time; // decelerating to zero velocity
            if ( type == 'easeInOutQuart' ) return time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration
            if ( type == 'easeInQuint' ) return time * time * time * time * time; // accelerating from zero velocity
            if ( type == 'easeOutQuint' ) return 1 + (--time) * time * time * time * time; // decelerating to zero velocity
            if ( type == 'easeInOutQuint' ) return time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration
            return time; // no easing, no acceleration
        };

        // Update the URL
        var updateURL = function (url, anchor) {
            if ( url === 'true' && history.pushState ) {
                history.pushState( {pos:anchor.id}, '', '#' + anchor.id );
            }
        };

        // Calculate how far to scroll
        var getEndLocation = function (anchor) {
            var location = 0;
            if (anchor.offsetParent) {
                do {
                    location += anchor.offsetTop;
                    anchor = anchor.offsetParent;
                } while (anchor);
            }
            location = location - headerHeight;
            if ( location >= 0 ) {
                return location;
            } else {
                return 0;
            }
        };
        var endLocation = getEndLocation(anchor);
        var distance = endLocation - startLocation;

        // Stop the scrolling animation when the anchor is reached (or at the top/bottom of the page)
        var stopAnimation = function () {
            var currentLocation = window.pageYOffset;
            if ( position == endLocation || currentLocation == endLocation || ( (window.innerHeight + currentLocation) >= document.body.scrollHeight ) ) {
                clearInterval(runAnimation);
            }
        };

        // Scroll the page by an increment, and check if it's time to stop
        var animateScroll = function () {
            timeLapsed += 16;
            percentage = ( timeLapsed / duration );
            percentage = ( percentage > 1 ) ? 1 : percentage;
            position = startLocation + ( distance * easingPattern(easing, percentage) );
            window.scrollTo( 0, position );
            stopAnimation();
        };


        // EVENTS, LISTENERS, AND INITS

        updateURL(url, anchor);
        var runAnimation = setInterval(animateScroll, 16);

    };

    // Check that anchor exists and run scroll animation
    var handleToggleClick = function (event) {

        // SELECTORS

        // Get anchor link and calculate distance from the top
        var dataID = this.getAttribute('href');
        var dataTarget = document.querySelector(dataID);
        var dataSpeed = this.getAttribute('data-speed');
        var dataEasing = this.getAttribute('data-easing');
        var dataURL = this.getAttribute('data-url');


        // EVENTS, LISTENERS, AND INITS

        event.preventDefault();
        if (dataTarget) {
            runSmoothScroll( dataTarget, dataSpeed || 500, dataEasing || 'easeInOutCubic', dataURL || 'false' );
        }

    };


    // EVENTS, LISTENERS, AND INITS

    // When a toggle is clicked, run the click handler
    Array.prototype.forEach.call(scrollToggles, function (toggle, index) {
        toggle.addEventListener('click', handleToggleClick, false);
    });

    // Return to the top of the page when back button is clicked and no hash is set
    window.onpopstate = function (event) {
        if ( event.state === null && window.location.hash === '' ) {
            window.scrollTo( 0, 0 );
        }
    };

}

})(window, document);

1 个答案:

答案 0 :(得分:0)

我想通了 - 我添加了

 $("html").bind("scroll mousedown DOMMouseScroll mousewheel keyup", function(){
    clearInterval(runAnimation);
 });

直接

var runSmoothScroll = function (anchor, duration, easing, url) {

runSmoothScroll是调用滚动动画的函数。因此,无论何时调用该函数,它都会将用于结束动画的函数clearInterval(runAnimation)添加到鼠标滚轮。我还找到了一种让脚本暂时禁用鼠标滚轮的方法。

  /* =============================================================



Smooth Scroll 3.2

Animate scrolling to anchor links, by Chris Ferdinandi.

http://gomakethings.com



Easing support contributed by Willem Liu.

https://github.com/willemliu



Easing functions forked from Gaëtan Renaudeau.

https://gist.github.com/gre/1650294



URL history support contributed by Robert Pate.

https://github.com/robertpateii



Fixed header support contributed by Arndt von Lucadou.

https://github.com/a-v-l



Infinite loop bugs in iOS and Chrome (when zoomed) by Alex Guzman.

https://github.com/alexguzman



Free to use under the MIT License.

http://gomakethings.com/mit/



* ============================================================= */



window.smoothScroll = (function (window, document, undefined) {



'use strict';



// Feature Test

if ( 'querySelector' in document && 'addEventListener' in window && Array.prototype.forEach ) {



    // SELECTORS



    var scrollToggles = document.querySelectorAll('[data-scroll]');





    // METHODS



    // Run the smooth scroll animation

    var runSmoothScroll = function (anchor, duration, easing, url) {
        /*
        //2/23/2014 Figured out how to disable mousewheel for a set amount of time
        //disable mousewheel function
        $("html").bind("scroll mousedown DOMMouseScroll mousewheel keyup", false);
        //pause until animated scrolling is finished, then enable mousewheel
        setTimeout(function(){
            $("html").unbind("scroll mousedown DOMMouseScroll mousewheel keyup", false);
        }, duration);
        */


        //alternatively, can end the animation prematurely if mousewheel is used
        $("html, body").bind("scroll mousedown DOMMouseScroll mousewheel keyup", function(){
            clearInterval(runAnimation);
        });





        // SELECTORS



        var startLocation = window.pageYOffset;



        // Get the height of a fixed header if one exists

        var scrollHeader = document.querySelector('[data-scroll-header]');

        var headerHeight = scrollHeader === null ? 0 : scrollHeader.offsetHeight;



        // Set the animation variables to 0/undefined.

        var timeLapsed = 0;

        var percentage, position;





        // METHODS



        // Calculate the easing pattern

        var easingPattern = function (type, time) {

            if ( type == 'easeInQuad' ) return time * time; // accelerating from zero velocity

            if ( type == 'easeOutQuad' ) return time * (2 - time); // decelerating to zero velocity

            if ( type == 'easeInOutQuad' ) return time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; // acceleration until halfway, then deceleration

            if ( type == 'easeInCubic' ) return time * time * time; // accelerating from zero velocity

            if ( type == 'easeOutCubic' ) return (--time) * time * time + 1; // decelerating to zero velocity

            if ( type == 'easeInOutCubic' ) return time < 0.5 ? 4 * time * time * time : (time - 1) * (2 * time - 2) * (2 * time - 2) + 1; // acceleration until halfway, then deceleration

            if ( type == 'easeInQuart' ) return time * time * time * time; // accelerating from zero velocity

            if ( type == 'easeOutQuart' ) return 1 - (--time) * time * time * time; // decelerating to zero velocity

            if ( type == 'easeInOutQuart' ) return time < 0.5 ? 8 * time * time * time * time : 1 - 8 * (--time) * time * time * time; // acceleration until halfway, then deceleration

            if ( type == 'easeInQuint' ) return time * time * time * time * time; // accelerating from zero velocity

            if ( type == 'easeOutQuint' ) return 1 + (--time) * time * time * time * time; // decelerating to zero velocity

            if ( type == 'easeInOutQuint' ) return time < 0.5 ? 16 * time * time * time * time * time : 1 + 16 * (--time) * time * time * time * time; // acceleration until halfway, then deceleration

            return time; // no easing, no acceleration

        };



        // Update the URL

        var updateURL = function (url, anchor) {

            if ( url === 'true' && history.pushState ) {

                history.pushState( {pos:anchor.id}, '', '#' + anchor.id );

            }

        };



        // Calculate how far to scroll

        var getEndLocation = function (anchor) {

            var location = 0;

            if (anchor.offsetParent) {

                do {

                    location += anchor.offsetTop;

                    anchor = anchor.offsetParent;

                } while (anchor);

            }

            location = location - headerHeight;

            if ( location >= 0 ) {

                return location;

            } else {

                return 0;

            }

        };

        var endLocation = getEndLocation(anchor);

        var distance = endLocation - startLocation;



        // Stop the scrolling animation when the anchor is reached (or at the top/bottom of the page)

        var stopAnimation = function () {

            var currentLocation = window.pageYOffset;

            if ( position == endLocation || currentLocation == endLocation || ( (window.innerHeight + currentLocation) >= document.body.scrollHeight ) ) {

                clearInterval(runAnimation);

            }

        };



        // Scroll the page by an increment, and check if it's time to stop

        var animateScroll = function () {

            timeLapsed += 16;

            percentage = ( timeLapsed / duration );

            percentage = ( percentage > 1 ) ? 1 : percentage;

            position = startLocation + ( distance * easingPattern(easing, percentage) );

            window.scrollTo( 0, position );

            stopAnimation();

        };





        // EVENTS, LISTENERS, AND INITS



        updateURL(url, anchor);
        var runAnimation = setInterval(animateScroll, 16);



    };



    // Check that anchor exists and run scroll animation

    var handleToggleClick = function (event) {



        // SELECTORS



        // Get anchor link and calculate distance from the top

        var dataID = this.getAttribute('href');

        var dataTarget = document.querySelector(dataID);

        var dataSpeed = this.getAttribute('data-speed');

        var dataEasing = this.getAttribute('data-easing');

        var dataURL = this.getAttribute('data-url');





        // EVENTS, LISTENERS, AND INITS



        event.preventDefault();

        if (dataTarget) {

            runSmoothScroll( dataTarget, dataSpeed || 500, dataEasing || 'easeInOutCubic', dataURL || 'false' );

        }



    };





    // EVENTS, LISTENERS, AND INITS



    // When a toggle is clicked, run the click handler

    Array.prototype.forEach.call(scrollToggles, function (toggle, index) {

        toggle.addEventListener('click', handleToggleClick, false);

    });



    // Return to the top of the page when back button is clicked and no hash is set

    window.onpopstate = function (event) {

        if ( event.state === null && window.location.hash === '' ) {

            window.scrollTo( 0, 0 );

        }

    };



}



})(window, document);