Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery scroll to div on hover and return to first element

I basically have a div with set dimensions and overflow: hidden. That div contains 7 child divs (but only shows one at a time) that I would like to be smoothly scrolled through vertically when their respective links are hovered.

However, the first section (div) doesn't have a link and is the default section when no link is hovered.

Take a look at this jsFiddle to see a basic structure of what I'm talking about: http://jsfiddle.net/YWnzc/

I've attempted to accomplish this with jQuery scrollTo but haven't been able to get it to work.

Any help would be greatly appreciated. Thanks.

like image 409
scferg5 Avatar asked Nov 18 '11 20:11

scferg5


3 Answers

Something like this?

http://jsfiddle.net/YWnzc/5/

code:

jQuery("#nav").delegate("a", "mouseenter mouseleave", function (e) {
    var i, self = this,
    pos;

    if (e.type == "mouseleave") {
    i = 0;
    }
    else {
    //Find out the index of the a that was hovered
        jQuery("#nav a").each(function (index) {
            if (self === this) {
            i = index + 1; //the scrollTop is just calculated from this by a multiplier, so increment
            return false;
            }
        });
    }

    //Find out if the index is a valid number, could be left undefined
    if (i >= 0) {

        //stop the previous animation, otherwise it will be queued
        jQuery("#wrapper").stop().animate({
        scrollTop: i * 200
        }, 500);
        //I would retrieve .offsetTop, but it was reporting false values :/
    }

    e.preventDefault();
});
like image 150
Esailija Avatar answered Sep 30 '22 17:09

Esailija


FYI : That JSFIDDLE you sent me to went to MooTools framework, not jQuery... fyi. (might be why its not working?

Copy and paste this code exactly and it will work in jQuery for animated scrolling.

Try this for smooth scrolling within the DIV, I tested it - it works great. You

    $(function() {

    function filterPath(string) {
        return string
        .replace(/^\//,'')
        .replace(/(index|default).[a-zA-Z]{3,4}$/,'')
        .replace(/\/$/,'');
    }

    var locationPath = filterPath(location.pathname);
    var scrollElem = scrollableElement('#wrapper');

    // Any links with hash tags in them (can't do ^= because of fully qualified URL potential)
    $('a[href*=#]').each(function() {

        // Ensure it's a same-page link
        var thisPath = filterPath(this.pathname) || locationPath;
        if (  locationPath == thisPath
            && (location.hostname == this.hostname || !this.hostname)
            && this.hash.replace(/#/,'') ) {

                // Ensure target exists
                var $target = $(this.hash), target = this.hash;
                if (target) {

                    // Find location of target
                    var targetOffset = $target.offset().top;
                    $(this).click(function(event) {

                        // Prevent jump-down
                        event.preventDefault();

                        // Animate to target
                        $(scrollElem).animate({scrollTop: targetOffset}, 400, function()      {

                            // Set hash in URL after animation successful
                            location.hash = target;

                        });
                    });
                }
        }

    });

    // Use the first element that is "scrollable"  (cross-browser fix?)
    function scrollableElement(els) {
        for (var i = 0, argLength = arguments.length; i <argLength; i++) {
            var el = arguments[i],
            $scrollElement = $(el);
            if ($scrollElement.scrollTop()> 0) {
                return el;
            } else {
                $scrollElement.scrollTop(1);
                var isScrollable = $scrollElement.scrollTop()> 0;
                $scrollElement.scrollTop(0);
                if (isScrollable) {
                    return el;
                }
            }
        }
        return [];
    }

});

FYI : Credit for this code does not go to me as an individual developer, although I did slightly tweak the code. The owner and creator of this code is Chris Coyier and you can find more about this scrolling code here: http://css-tricks.com/snippets/jquery/smooth-scrolling/

like image 32
Downpour046 Avatar answered Sep 30 '22 16:09

Downpour046


Here's a working example: http://jsfiddle.net/YWnzc/7/

And the code (pretty similar to rizzle's, with a couple changes that I'll explain):

$('a').hover(function(){
    var selector  = $(this).data('section');
    var scrollAmount = $(selector).offset().top + $('#wrapper')[0].scrollTop - 129;
    $('#wrapper').animate({scrollTop: scrollAmount}, 250);
},function(){
    $('#wrapper').animate({scrollTop: 0}, 250);
});

First, var selector = $(this).data('section'); because in jsFiddle, the href attribute was returning the full path of the page + the hash. So I changed it to an html5 data attribute (data-section).

The next line is similar to rizzle's, except that we grab the offset of the section and add it to the current scrollTop value of the #wrapper. As he pointed out, there are some weird offset issues going on still, and I found that subtracting 129 did the trick. While this 129 number might seem like something that is likely to break, I did test out changing the sizes of the sections, making them not equal, etc, and it continued to work. I'm using Chrome, and perhaps a non-webkit browser would need a different constant to subtract. But it does seem like that 129 number is at least some kind of constant.

The rest should be pretty self-explanatory.

One thing to note: as you move your cursor over the <a> tags, the content of the #wrapper div will seem to jump around, but that's just because the mouseleave part of the hover event briefly gets triggered as the cursor moves. I'm sure you can solve that one though :)

like image 43
maxedison Avatar answered Sep 30 '22 18:09

maxedison