问题描述:

Here's a live version of the page in question: http://agoodman.com.au/index1.html

I'm using Bootstrap to build a one-pager website, and scrollTo is being used to scroll up/down the different sections. There is a top navbar, with the code:

<ul class="nav">

<li class="active"><a href="#intro" onclick="$.scrollTo( '#intro', 600 );">Top</a></li>

<li><a href="#service" onclick="$.scrollTo( '#service', 600 );">What we do</a></li>

<li><a href="#howitworks" onclick="$.scrollTo( '#howitworks', 600 );">How it works</a></li>

<li><a href="#fees" onclick="$.scrollTo( '#fees', 600 );">Our fees</a></li>

<li><a href="#why" onclick="$.scrollTo( '#why', 600 );">Why do it?</a></li>

<li><a href="#map" onclick="$.scrollTo( '#map', 600 );">Map</a></li>

<li><a href="#contact" onclick="$.scrollTo( '#contact', 600 );">Contact</a></li>

</ul>​

The scrolling works fine when you click on the navbar with the mouse, no weird behaviour at all. I'm then using this jquery code to control the navbar with the up/down arrows of the keyboard:

$(document).keyup(function(e) {

var p = $("li.active");

if (e.keyCode === 38) {

p.prev().find("a").click();

} else if (e.keyCode === 40) {

p.next().find('a').click();

}

});

This works, for the most part. However, there are two problems that I'd like to solve:

1. When pressing up/down, the page moves up/down one small jump (as if pressing an arrow key on any website does) and then scrolls to the next div. I tried putting event.preventDefualt(); in the jquery if/else statement but it didn't do anything. Any ideas on how to prevent the default up/down action here?

2. Pressing the "up" key causes the page to scroll up two sections rather than one. For instance, go to the "#why" section, then press up. It scrolls to "#fees" then scrolls again to "#howitworks". Perhaps scrollspy.js is conflicting here?

Would appreciate being pointed in the right direction in this one.

Cheers

网友答案:

Use keydown. Then either return true and e.preventDefault() will do what you want.

网友答案:

Not really sure why the page would skip, could be because of the find and the position of where you are in your hash list. I wrote a small snippet for code organization so its easier to debug where you are.

EDIT: Okay, I finally revised the code to make it work properly. Earlier, I kind of figured it wouldn't work, but I wanted to give you a skeleton of how to handle the scrolls.

Note:

  1. $("a") fetches a list of all anchors
  2. window.location.hash.slice(1) gets the current hash that you are on, in case you clicked on a link
  3. anchors.index is the index of the anchor you are on (gathered from step 1)
  4. anchors.get simply fetches the next position
  5. currentHash.hash is the hash of the next address you are fetching from

    var anchors = $("a.links");
    var currentPos = 0;
    var nextPos = 0;
    var current = window.location.hash.slice(1); //get current hash;
    
    $('#navbar').scrollspy();
    
    $(document).ready(function(){       
        $(document).keyup(function(e){
             e.preventDefault();
            currentPos = anchors.index($('a[href$="' + $('input[name="hash"]').val() + '"]'));
            //currentPos = anchors.index($('a[href$="' + current + '"]'));
             if(e.keyCode === 38){
                scrollUp(currentPos);
             } else if (e.keyCode === 40){
                scrollDown(currentPos);
             }
    
        });
    
        function scrollUp(pos){
            currentHash = anchors.get(pos-1);
            if(!(currentHash===undefined) && (pos-1) >= 0){
                current = currentHash.hash;
            }
             $(document).scrollTo(current,600);
    
        }
    
        function scrollDown(pos){
            currentHash = anchors.get(pos+1);
            if(!(currentHash===undefined)){
                current = currentHash.hash;
            }
             $(document).scrollTo(current,600);
        }
    });
    

Tip:

I'd associate a class to your links like:

 <a class="links" href="#service" ....>

then in step 1 of the notes you could do a selector:

 $(a) will then be $(a.links)

EDIT2 : I edited the above javascript to make use of the changes below:

I found an unfortunate way to use scrollspy. Apparently, they use prototypes to wrap up their functions, and you really can't call those methods directly. So the workaround is this:

place this html code into your webpage:

<input type="hidden" name="hash" value="" />

Then open up scrollspy, go down to the prototyping where it gives you "activates" and enter in this code:

$('input[name="hash"]').val(this.activeTarget);

above the line:

active.trigger('activate')
相关阅读:
Top