1

The general idea to the site i am designing is to scroll through a set of menu items horizontally and incrementally underneath a static div that will magnify(increase dimensions and pt size) the contents of a menu items. I don't really need help with the magnify portion because i think it's as simple as adding a mag class to any of the menuItem divs that go underneath the static div. I have been messing with this for a few weeks and the code I have for incrementally scrolling, so far, is this:

   $(document).ready(function () {

    currentScrollPos = $('#scrollableDiv').scrollTop(120); //sets default scroll pos


    /*The incrementScroll function is passed arguments currentScrollPos and UserScroll which are variables that i have initiated earlier in the program, and then initiates a for loop. 
        -The first statement sets up the variables: nextScrollPos as equal to the currentScrollPos(which by default is 120px) plus 240px(the distance to next menuItem), prevScrollPos as equal to the currentScrollPos(which by default is 120px) minus 240px(the distance to next menuItem).  
        -The second Statement checks to see if the user has scrolled using var userScroll
        -The third statement sets: var CurrentScroll equal to the new scroll position and var userScroll to false*/

    function incrementScroll(currentScrollPos, userScroll) {
        for (var nextScrollPos = parseInt(currentScrollPos + 240, 10),
        prevScrollPos = parseInt(currentScrollPos - 240, 10); //end first statement
        userScroll == 'true'; console.log('dude'),   //end second statement and begining of third
        currentScrollPos = scrollTop(), userScroll = 'false') { 


            if (scrollTop() < currentScrollPos) {
                $('#scrollableDiv').animate({
                    scrollTop: (parseInt(prevScrollPos, 10))
                }, 200);
                console.log('scrolln up')
            } else if (scrollTop() > currentScrollPos) {
                $('#scrollableDiv').animate({
                    scrollTop: (parseInt(nextScrollPos, 10))
                }, 200);
                console.log('scrolln down')//fire when 
            }

        }
    }

    $('#scrollableDiv').scroll(function () {
        userScroll = 'true';
        _.debounce(incrementScroll, 200); //controls the amount of times the incrementScroll function is called
        console.log('straight scrolln')
    });
});

I have found a variety of solutions that are nigh close: such as a plugin that snaps to the next or previous div horizontally demo, another solution that also snaps and is based on setTimeout demo, but nothing that nails incrementally scrolling through divs. I also found a way to control the rate at which a user may scroll through the menuItems using debounce which is included in the above code.

The console.logs inside the loop do not fire when I demo the code in jsfiddle which leads me to believe the problem lies within the loop. I'm a noob though so it could be in syntax or anywhere else in the code for that matter. Also in the second demo, i have provided the css for the horizontal static div, but the moment I put it in my html it keeps the js from working.

I would like to write the code instead of using a plugin and any help would be appreciated! Also, thank you ahead of time!

teamair
  • 15
  • 4
  • Can you make an image of thing you want to do? – Gromo Mar 19 '14 at 05:06
  • @Gromo will this suffice? [link](http://jsfiddle.net/teamair/np9Wu/27/) – teamair Mar 19 '14 at 15:35
  • Is [this](http://jsfiddle.net/np9Wu/32/) what you're looking for? If not, try to make a picture in photoshop what you want to do – Gromo Mar 20 '14 at 05:00
  • That's sorta what i'm looking for except with animate and ScrollTop to control how fast you scroll through the MenuItems. Also i want the menuContainer to show all menu items like [this](http://s26.postimg.org/6mlgtceih/Screen_Shot_2014_03_20_at_10_50_16_AM.png) – teamair Mar 20 '14 at 14:59
  • @Gromo I did notice that you used animate and scrollTop so disregard part of the last comment. I did provide a screenshot of my PSD, so hopefully that helps. – teamair Mar 20 '14 at 15:05
  • just one more thing: as I understand, "zoom" container will stay in one position, so, how are you going to scroll to bottom menu items? I will wait for your response tomorrow – Gromo Mar 20 '14 at 15:15
  • @Gromo The "zoom" div is actually a static div and not a container at all. The menu item divs are scrolling underneath the "zoom" div independently. The method I tried to use in my code is to set a default scroll position so that a menuItem is lined up underneath the zoom div to start. Then every user's single scroll moves the next menuItem underneath the "zoom" div and then the next scroll input moves the next menuItem underneath the "zoom" div and so on and so on. – teamair Mar 20 '14 at 20:58

1 Answers1

0

Try this fiddle. Menu container height is 960px to show 4 menu items. "Zoom" div is positioned absolutely at top. When you scroll mouse over this div, menu items shifts to top/bottom. I had to add additional div to bottom to be able to scroll to last 3 menu items. JS code:

jQuery(document).ready(function($){

    var current = 0;
    var menu = $('.menu-container').scrollTop(0);
    var items = menu.find('.menu-item');
    var zoom = $('.zoom');


    function isVerticalScroll(event){
        var e = event.originalEvent;
        if (e.axis && e.axis === e.HORIZONTAL_AXIS)
            return false;
        if (e.wheelDeltaX)
            return false;
        return true;
    }

    function handleMouseScroll(event){
        if(isVerticalScroll(event)){
            var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;
            current += (delta > 0 ? 1 : -1);

            if(current < 0)
                current = 0;
            if(current >= items.length){
                current = items.length - 1;
            }

            menu.stop().animate({
                "scrollTop": current * 240
            }, 300);

            items.removeClass('current').eq(current).addClass('current');

            event && event.preventDefault();
            return false;
        }
    }

    zoom.on({
        "MozMousePixelScroll": handleMouseScroll,
        "mousewheel": handleMouseScroll
    });
});

Hope it will help.

Gromo
  • 1,609
  • 1
  • 13
  • 14
  • This works almost exactly how I want it to! Do you mind explaining it to me a bit? The next step would be to make this work regardless of input device(arrow keys on keyboard and scrolling on a track pad). Also I want to bind the scroll of this div to the windows scrollbar as well i.e. I pull down the scroll bar and the same scroll behavior that works on menuContainer also works on the window element. Is that possible? – teamair Mar 21 '14 at 18:38
  • Almost everything is possible except some limits. Menu container element is not scrollable by itself, and I handle mousewheel event on "zoom" element to scroll menu container to top/bottom to next element. It's simple for mousewheel; adding key up/down support is also simple, but I'm not so sure about track pad. Handling window scroll event is also possible, but there are a lot of questions "how it will work if...". So the best way to understand its logic is to find working example somewhere and try to mimic it – Gromo Mar 22 '14 at 04:43
  • Also in regards to your [example] (http://jsfiddle.net/teamair/LQyy5/), why is the last div necessary to allow me to scroll to the last three menuItems. Thank you for your help i really appreciate it! – teamair Mar 23 '14 at 22:04
  • Because you cannot scroll element if it reaches the end (just think about it). Also you can use CSS `top` value and `position:relative` to scroll content - in that case you don't need last element, but when you scroll to the last one, bottom part of your scrollable container will be empty. – Gromo Mar 24 '14 at 05:40
  • haha duh! I guess I wasn't really thinking. My solution would be to create some script that clones a menuItem from the top and appends it to menuContainer giving the illusion of infinite scroll. The only problem with that is when i use prepend for up scrolls it will shift the scroll position, which I found some examples of [here](http://stackoverflow.com/questions/9834143/jquery-keep-window-from-changing-scroll-position-while-prepending-items-to-a-l) – teamair Mar 24 '14 at 15:33
  • @teamair In your case you should shift scrollTop position everytime you prepend new element, recalculate it. There will be additional offset calculation (as elements' order is changing), but it's not too much. On each scroll event you should see "where I am now", then reorder items that are out of visible area, recalculate & update offset, then scroll to the next position. – Gromo Mar 24 '14 at 16:48