Динамически изменяющийся класс для элемента с фиксированной навигацией на основе прокрутки страницы (одностраничный веб-сайт) - PullRequest
2 голосов
/ 02 февраля 2012

В настоящее время я немного застрял в проблеме и, кажется, не могу найти решение.

Я пытаюсь создать фиксированную навигацию на сайте, на котором изменяется активный класс при прокрутке, а также при нажатии. Вот хороший пример навигации, которую я пытаюсь достичь - kiskolabs.com/

У меня почти получилось, что он работает со следующим кодом, но после того, как первые 2 элемента навигации работают как надо, я обнаружил, что состояние элемента навигации не меняется в правильном месте. Не уверен, что я ошибся, но якорные ссылки все еще идут в правильное место, только активное состояние не меняется после пары. Любые идеи кто-нибудь? Ниже приведен код.

HTML

<section id="1">
    <nav>
        <ul>
            <li><a href="#1">1</a></li>
            <li><a href="#2">2</a></li>
            <li><a href="#3">3</a></li>
            <li><a href="#4">4</a></li>
        </ul>
    </nav>
    <p>All content here</p>
</section>
<section id="2">
    <p>All content here</p>
</section>
<section id="3">
    <p>All content here</p>
</section>
<section id="4">
    <p>All content here</p>
</section>

И я использую jquery:

$(document).ready(function () {
var $sections = $('section');  // all content sections
var $navs = $('nav > ul > li');  // all nav sections

var topsArray = $sections.map(function() {
return $(this).position().top - 300;  // make array of the tops of content
}).get();                                 //   sections, with some padding to
                                      //   change the class a little sooner
var len = topsArray.length;  // quantity of total sections
 var currentIndex = 0;        // current section selected

var getCurrent = function( top ) {   // take the current top position, and see which
for( var i = 0; i < len; i++ ) {   // index should be displayed
    if( top > topsArray[i] && topsArray[i+1] && top < topsArray[i+1] ) {
        return i;
    }
}
};

// on scroll,  call the getCurrent() function above, and see if we are in the
//    current displayed section. If not, add the "selected" class to the
//    current nav, and remove it from the previous "selected" nav
$(document).scroll(function(e) {
var scrollTop = $(this).scrollTop();
var checkIndex = getCurrent( scrollTop );
if( checkIndex !== currentIndex ) {
    currentIndex = checkIndex;
    $navs.eq( currentIndex     ).addClass("selected").siblings(".selected").removeClass("selected");
}
});

});

Ответы [ 2 ]

4 голосов
/ 05 апреля 2013

Это прекрасно работает: DEMO

Все, что вам нужно сделать, это добавить class = "link" на все ваши <a> теги, и тогда ему будет присвоен класс "active", когда будет достигнут элемент с таким же идентификатором, как у href.(если вы хотите, чтобы ваша первая ссылка выделялась при загрузке страницы, укажите ей активный класс в вашем HTML)

Так, например, <a href="#about_us"></a> будет активным при достижении <div id="about_us"></div>.

The " -40"предназначен для компенсации высоты фиксированного жатки, поэтому замените / удалите его при необходимости.

// ADDS ACTIVE CLASS TO LINKS WHEN SECTION WITH THE SAME SELECTOR AS THE HREF IS REACHED (CLASS .LINK IS NEEDED ON ALL <a> TAGS)

$(document).ready(function () {
    $(window).scroll(function () {

        var y = $(this).scrollTop();

        $('.link').each(function (event) {
            if (y >= $($(this).attr('href')).offset().top - 40) {
                $('.link').not(this).removeClass('active');
                $(this).addClass('active');
            }
        });
    });
});
1 голос
/ 04 марта 2012

Вот следующие 3 полезные похожие ссылки: -

  1. Учебник
  2. StakoverFlow Link
  3. Пример скрипки

HTML:

<div id="body">
    <div id="header"> This header will turn blue if it moves past that line and stay green BEFORE that line</div>
    <hr/>
    <div id="largebody"></div>
</div>

JAVASCRIPT:

$("#body").scroll( function() {
    var value = $(this).scrollTop();
    if ( value > 120 )
        $("#header").css("border", "1px solid blue");
    else
        $("#header").css("border", "1px solid green");
});

CSS:

body {
    font: 12px arial;
}

#header {
    height: 40px;
    width: 100%;
    position: absolute;
    top: 0px;
    border: 1px solid green;
}

hr {
    position: relative;
    top: 120px;
    margin: 0px;
}

#body {
    overflow: scroll;
    height: 300px;
}
#largebody {
    height: 900px;
}
body {
    padding: 0px;
}

Надеюсь, это поможет вам.

...