Submit your widget

jQuery Very Long scroll Dropdown Menus

Created 13 years ago   Views 17307   downloads 2429    Author Chris Coyier
jQuery Very Long scroll Dropdown Menus
View DemoDownload
117
Share |

jQuery Makes it Tick

I’m going to dump the code all in here just for quick reference. I commented it, so it should be fairly easy to follow. It’s over 60 lines, but don’t worry too much, it’s fairly simple.

  1. Set a maximum height to the dropdowns
  2. On hover, reveal the submenu
  3. Calculate a speed multiplier based on the height of the submenu
  4. Watch for mouse movement in the menu
  5. Scroll the menu with the mouse movement, based on the multiplier
  6. On mouse out, close the menu

var maxHeight = 400;

$(function(){

    $(".dropdown > li").hover(function() {

         var $container = $(this),
             $list = $container.find("ul"),
             $anchor = $container.find("a"),
             height = $list.height() * 1.1,       // make sure there is enough room at the bottom
             multiplier = height / maxHeight;     // needs to move faster if list is taller

        // need to save height here so it can revert on mouseout
        $container.data("origHeight", $container.height());

        // so it can retain it's rollover color all the while the dropdown is open
        $anchor.addClass("hover");

        // make sure dropdown appears directly below parent list item
        $list
            .show()
            .css({
                paddingTop: $container.data("origHeight")
            });

        // don't do any animation if list shorter than max
        if (multiplier > 1) {
            $container
                .css({
                    height: maxHeight,
                    overflow: "hidden"
                })
                .mousemove(function(e) {
                    var offset = $container.offset();
                    var relativeY = ((e.pageY - offset.top) * multiplier) - ($container.data("origHeight") * multiplier);
                    if (relativeY > $container.data("origHeight")) {
                        $list.css("top", -relativeY + $container.data("origHeight"));
                    };
                });
        }

    }, function() {

        var $el = $(this);

        // put things back to normal
        $el
            .height($(this).data("origHeight"))
            .find("ul")
            .css({ top: 0 })
            .hide()
            .end()
            .find("a")
            .removeClass("hover");

    });

    // Add down arrow only to menu items with submenus
    $(".dropdown > li:has('ul')").each(function() {
        $(this).find("a:first").append("<img src='images/down-arrow.png' />");
    });

});