J Young
J Young

Reputation: 755

Display arrow below active navigation item

I'm currently building a portfolio site to showcase some of the work I've done whilst at university and settled on a one page design. What I'd like the site to do is as you scroll down and 'enter' the various sections, a down arrow below the navigation bar will horizontally slide across (as an animation) to below the current active section/navigation item.

What have I tried? I'll be honest, nothing. I'm not looking for an answer, though that would be nice, I just need a starting point. The main issue is that I really have no idea how to 'snap' it to be below each list item so that it is perfectly central to the text and caters for different display resolutions.

HTML

  <div id="header">
        <div class="topbar">
        </div>
        <div class="headbar">
            <nav>
                <div class="wrapper">
                    <ul>
                        <li><a href="#home">Home</a></li>
                        <li><a href="#about">About</a></li>
                        <li><a href="#work">Projects</a></li>
                        <li><a href="#contact">Contact</a></li>
                        <li><a href="#">Blog</a></li>
                    </ul>
                </div>
            </nav>
        </div>
        <div class="shadow">
        </div>
        <div class="current"></div>
    </div>

CSS

.wrapper {
width: 920px;
margin: 0 auto;
}

#header {
position: fixed;
width: 100%;
}

#header .topbar {
height: 10px;
background-color: #386c93;
}

#header .headbar {
height: 60px;
background: #f2f2f2;
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMmYyZjIiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjY2JlYmZmIiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L2xpbmVhckdyYWRpZW50PgogIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZC11Y2dnLWdlbmVyYXRlZCkiIC8+Cjwvc3ZnPg==);
background: -moz-linear-gradient(top, #ffffff 0%, #f2f2f2 100%, #cbebff 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#f2f2f2), color-stop(100%,#cbebff));
background: -webkit-linear-gradient(top, #ffffff 0%,#f2f2f2 100%,#cbebff 100%);
background: -o-linear-gradient(top, #ffffff 0%,#f2f2f2 100%,#cbebff 100%);
background: -ms-linear-gradient(top, #ffffff 0%,#f2f2f2 100%,#cbebff 100%);
background: linear-gradient(to bottom, #ffffff 0%,#f2f2f2 100%,#cbebff 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#cbebff',GradientType=0 );
border-bottom: 1px solid #9b9999;
}

#header .shadow {
height: 17px;
background-image: url('shadow.png');
background-repeat: none;
background-position: center;
}

#header a {
color: #5c5959;
text-decoration: none;
}

#header a:hover {
color: #0092ff;
}

#header .current {
background-image: url('nav-pointer.PNG');
height: 19px;
width: 22px;
margin-top: -18px;
margin-left: 715px;
}

#header ul{
padding-top: 20px;
text-align: center;
list-style: none;
}

#header li {
font-size: 16px;
//float: left;
display: inline;
color: #5c5959;
padding: 30px;
}

I've created a JSFiddle just to make life easier for everyone - http://jsfiddle.net/GW6CG/2/ - apologies if the CSS is a little messy, I intend to clean that up at some point.

Alternatively you can view the site live here: http://www.jonline.me.uk/dev/

Many thanks for your time!

Upvotes: 0

Views: 873

Answers (2)

gvee
gvee

Reputation: 17161

I wrote something a while ago that you can easily use as a skeleton for this: http://jsfiddle.net/LYqVk/2/

The JQuery looks like this:

$('a[href*=#]').click(function (e) {
    e.preventDefault();

    var id = $(this).attr('href');
    var scrollTo = $(id).offset().top;

    $('html,body').animate({
        'scrollTop': scrollTo
    }, 500);
});

$(document).scroll(function () {
    highlightSection();
});

function highlightSection() {
    // Where's the scroll at?
    var currentPosition = $(this).scrollTop();

    // Remove highlights from all
    $('a[href*=#]').removeClass('highlighted');

    // Loop over each section
    $('#content .section').each(function () {
        // Calculate the start and end position of the section
        var sectionStart = $(this).offset().top;
        var sectionEnd = sectionStart + $(this).height();

        // If the current scroll lies between the start and the end of this section
        if (currentPosition >= sectionStart  && currentPosition < sectionEnd) {
            // Highlight the corresponding anchors
            $('a[href=#' + $(this).attr('id') + ']').addClass('highlighted');
        }
    });
};

highlightSection();

Have a good read of the comments in the code, hopefully they are explanatory enough but just in case they're not the basic process is this:

  1. Work out where we are on the page - .scrollTop()
  2. Loop over the .sections
  3. If the current position lies between the top and bottom of a section, that's the one we want to highlight*

    • in your case that would be with an arrow.

Upvotes: 1

Paulo R.
Paulo R.

Reputation: 15609

There's no point in creating this functionality from scratch. Lots of plugins have already been created to accomplish this. One is scrollit.js.

Also, if you'd like to add fart noises as you scroll, check out fartscroll.js

Hope I've helped.

Upvotes: 2

Related Questions