开发者

How to enforce a "smooth scrolling" rule for mousewheel, jQuery?

How are you? My Question:

How can I control or specify the way a document scrolls to the position of desire described by either the mouse scrollwheel, and/or grabbing the scrollbar. What I want would be to overcome the particular default method of page scrolling.

As it currently works the page jumps right to x# of pixels down per 'notch' that is progressed on the scrollwheel. Or goes directly to where you drag the scroll bar. What i'm looking for is a simple extension to jquery that can apply certain scrolling rules.The principals are simple. Imposed acceleration, thi开发者_如何学JAVAs would prevent the page from moving too fast without first accelerating. settable as a rate of in px/sec- with the option to apply easing functions...There is a maximum px/sec that the page can slide/move/drag. and thirdly is a deceleration rule, applied as the page approaches it's destination position (in %, px?). This may have to be calculated in one of many ways, and may be trickier. ie when scrolling the last 25 pixels to the destination position, the deceleration applys. There's more... The main concern I'd want to prepare for would be ensuring that small page scrolls we're supported fully and not glitchy.

What sort of jQuery approaches could be used to control the document in this way? _kyle

Update::: Thanks For following this Q, if you are. Great News. Found a great plugin that hopefully can be handled to be supporting the desired effects, yo! I've implemented a whole page container and used this nifty jScrollPane script to commandeer if you will the scrolling of the page http://jscrollpane.kelvinluck.com/fullpage_scroll.html

There is already a big difference in the performance of the page. Each scroll notch from the wheel is a third to a half of the browsers native scroll notch, so it moves slower, which is fine, surly that's adjustable.

We still have the stall-stall-stall method of page movement, though.

I myself write javascript, but more it's like I re-write it. What I think needs to be done is a "queue" built of pixels to be scrolled along a page, with the total time compounded: and then an animation footprint defined and executed as three phases, an in easing acceleration, maxscrollspeed phase, and decel phase.

Could anybody offer any suggestions as to how we

  1. Detatch the mousescrollwheel from its native function of scrolling the page.

  2. listen for notches of the mousescroll; and in the event of a notch: initialize the corefunction to start the movement of the page, but also listen for and add additional notch clicks to "queue" that is re-calulated and applied to the scroll of the window replacing the previous totaldistancetoscroll, before calculating the next totaldistancetoscroll, which provides a way to anticipate the destination and decelerate. The corefunctions to start movement wouldn't want to be restarted, cause multiple notch clicks will probably happen while accelerating, but just a recalculated when and where to decelerate should be applied.

Sorry again for not posting any actual code yet, not exactly sure where to start and was hoping someone might know if mwintent will work for this and if so: might also have some ideas how to apply a deceleration to the scroll, which seems to be the only two difference between the desired effect and the state of the current plug-ins that are similar.


What I wanted to do was to simulate browser's smooth scrolling on browsers that don't support it natively, has it turned off by default or has bad implementation of it.

Thanks to lumbric's answer I've came up with this solution:

$(function () {

    var top = 0,
        step = 55,
        viewport = $(window).height(),
        body = $.browser.webkit ? $('body') : $('html'),
        wheel = false;


    $('body').mousewheel(function(event, delta) {

        wheel = true;

        if (delta < 0) {

            top = (top+viewport) >= $(document).height() ? top : top+=step;

            body.stop().animate({scrollTop: top}, 400, function () {
                wheel = false;
            });
        } else {

            top = top <= 0 ? 0 : top-=step;

            body.stop().animate({scrollTop: top}, 400, function () {
                wheel = false;
            });
        }

        return false;
    });

    $(window).on('resize', function (e) {
        viewport = $(this).height();
    });

    $(window).on('scroll', function (e) {
        if (!wheel)
            top = $(this).scrollTop();
    });

});

Put some content on your page long enough to have scrollbars. Then use your mouse wheel. It works on every browser. I've used jQuery-1.7.2 and the mousescroll plugin mentioned in the lumbric's post.

The step var means how many pixels to scroll on every mouse wheel event. ~55 pixels is what I've found to be the default value on most systems.

Also you may want to change the speed for the animation, other than that the rest of the code logic is needed to get the things work properly.

EDIT: Note that I have extracted the above functionality into a convenience jquery plugin.


I had a very simmilar problem. I wanted to change the scroll function of a normal page. I want every scroll to be exactly of an specific height so that the page stops in very specific positions only.

I realized it in the following way:

1. Used Plugins

Download and include the following 2 jQuery plugins and jQuery itself:

  • scrollTo (see also here)
  • mousewheel (see also here)

2. Mousewheel event

The easiest way is to use the mousewheel plug in that way:

$('body').mousewheel(function(event, delta) { /* code here */ });

The variable delta is then negative or positive, depending if the wheel was scrolled up or down. If you return false I think (!) it disables the normal scroll.

3. Scroll method

In order to scroll the page I used scrollTo, but any other plugin (like Smooth Scroll suggested in the other answer) should also do it.

4. Complete code

Place this in the head part of you HTML-File:

<script type="text/javascript" src="jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="jquery.scrollTo-1.4.2-min.js"></script>
<script type="text/javascript" src="jquery.mousewheel.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {          
        $('body').mousewheel(function(event, delta) {
            # This if might not be very elegant!
            if (delta < 0) {
                $('body').scrollTo('+=100', 1500 );
            }
            else
                $('body').scrollTo('-=100', 1500 );

            return false;
        });
    });
</script>

5. Demo

I created a demo here: http://pastehtml.com/view/ba0ziusqk.html


You want to give this one a try

https://github.com/galambalazs/smoothscroll-for-websites

it has nice settings to adjust the animation and seems to be well maintained.

// Scroll Variables (tweakable)
var defaultOptions = {

    // Scrolling Core
    frameRate        : 100, // [Hz]
    animationTime    : 1200, // [ms]
    stepSize         : 80, // [px]

    // Pulse (less tweakable)
    // ratio of "tail" to "acceleration"
    pulseAlgorithm   : true,
    pulseScale       : 4,
    pulseNormalize   : 1,

    // Acceleration
    accelerationDelta : 50,  // 50
    accelerationMax   : 3,   // 3

    // Keyboard Settings
    keyboardSupport   : true,  // option
    arrowScroll       : 50,    // [px]

    // Other
    touchpadSupport   : false, // ignore touchpad by default
    fixedBackground   : true, 
    excluded          : ''    
};


here is a good solution check this out http://ataredo.com/morphology/lucidscroll/

<script src="file-directory/jquery.js"></script>
<script src="file-directory/lucid.js"></script>

<script>
$(window).on('load', function() {

  $(this).impulse();
});
</script>


Karl Swedberg has made a jQuery plugin called Smooth Scroll, which sounds like it may be just what you're after.


my solution with Mobile effect

    <div id="parent">
    <div id="child">aaa aaaaaaaaa aaaaaaaa aaaaaaaaaaaa abbbbbbbbbbbbbbbbb bbbbbbbbbbbbcc ccccccc ccccccccccc cccccccd ddddddd ddd ddddd ddddd dddddddd aaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaa abbbbbbbbbbbbbbbbb bbbbbbbbbbbbcc ccccccc ccccccccccc cccccccd ddddddd ddd ddddd ddddd dddddddd aaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaa abbbbbbbbbbbbbbbbb bbbbbbbbbbbbcc ccccccc ccccccccccc cccccccd ddddddd ddd ddddd ddddd dddddddd aaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaa abbbbbbbbbbbbbbbbb bbbbbbbbbbbbcc ccccccc ccccccccccc cccccccd ddddddd ddd ddddd ddddd dddddddd aaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaa abbbbbbbbbbbbbbbbb bbbbbbbbbbbbcc ccccccc ccccccccccc cccccccd ddddddd ddd ddddd ddddd dddddddd aaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaa abbbbbbbbbbbbbbbbb bbbbbbbbbbbbcc ccccccc ccccccccccc cccccccd ddddddd ddd ddddd ddddd dddddddd aaaaaaaaaaaa aaaaaaaa aaa</div>

        #parent {
        width: 300px;
        height: 300px;
        background-color: #aaa;
        margin: auto auto;
        overflow: hidden;
    }
    #child {
        width: 200px;
        height: 800px;
        background-color: #999;
        margin: auto auto;
        text-align: justify;
        position: relative;
        top: 0;
        -webkit-transition: all 0.5s ease-out;
}




$('#parent').bind('mousewheel', function (e) {
        if (!(e.originalEvent.wheelDelta == 120)) {
            var top = parseInt($("#child").css("top"));
            $("#child").css("top", (top - 100) + "px");
            top = parseInt($("#child").css("top"));
            if (top <= -500) {
                setTimeout(function () {
                    $("#child").css("top", "-500px");
                }, 100);
            }
        } else {
            var top = parseInt($("#child").css("top"));

            $("#child").css("top", (top + 100) + "px");
            top = parseInt($("#child").css("top"));
            if (top >= 0) {
                setTimeout(function () {
                    $("#child").css("top", "0");
                }, 100);
            }
        }
    });

THE DEMO


var $window              = $(window),
    scrollDistance   = 300,
    scrollSpeed      = 500,
    scrollEffect     = 'swing',
    scrollAmount     = 1,
    smoothScroll;

if (! ('ontouchstart' in document.documentElement) && ! $('body').hasClass('modal-open')) {

        $window.on("mousewheel DOMMouseScroll", function (event) {

            event.preventDefault();

            if (smoothScroll) {

                // Start scrolling while waiting for final scoll amount (user stopped wheeling)
                if (scrollAmount == 1) {
                    var delta = event.originalEvent.wheelDelta / 120 || -event.originalEvent.detail / 3;
                    var finalScroll = $window.scrollTop() - parseInt(delta * (scrollDistance * scrollAmount));

                    $('html, body').stop().animate({ scrollTop: finalScroll }, scrollSpeed, scrollEffect);
                }

                // Increase scroll amount
                scrollAmount++;

                // Clear current timeout
                clearTimeout(smoothScroll);
            }

            // Set animated scroll
            smoothScroll = setTimeout(function() {

                var delta = event.originalEvent.wheelDelta / 120 || -event.originalEvent.detail / 3;
                var scrollTop = $window.scrollTop();
                var finalScroll = scrollTop - parseInt(delta * (scrollDistance * scrollAmount));

                // Reset scroll amoount
                scrollAmount = 1;

                $('html, body').stop().animate({ scrollTop: finalScroll },
                    (scrollSpeed*scrollAmount),
                    scrollEffect
                );

                // Clear timeout holder
                smoothScroll = null;

            }, 100);

        });
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜