jQuery меняет CSS на навигации, когда div # прокручивается в поле зрения - PullRequest
7 голосов
/ 24 мая 2010

Я хочу воссоздать эффект, используемый на этом сайте: http://www.brizk.com/

Сайт использует одну большую страницу, которая прокручивается вниз. При прокрутке вниз и прохождении различных разделов навигация по меню слева меняет класс css на «текущий», когда появляется соответствующий div.

Я предполагаю, что это можно сделать с помощью jQuery, используя $ (window) .height ();

Я довольно новичок в jQuery, и я хочу написать что-то вроде этого (в терминах непрофессионалов):

  • Получить высоту окна браузера - если div # content1 равен 100px сверху и / или 200px снизу, измените меню с # link1 на '.current' - иначе удалите .current из всего меню ссылки

... и повторите для 4 различных дел содержимого.

Кто-нибудь может указать мне правильное направление? Спасибо.

Ответы [ 3 ]

24 голосов
/ 24 мая 2010

Я не смотрел на пример кода (веселее бросить вызов самому себе: P), но так я бы это сделал - демо здесь .

Я сохранил положение каждого блока элементов, чтобы минимизировать количество вызовов DOM, а затем просто провел поиск в массиве. Чтобы помочь вам понять некоторые из переменных.

$(window).height() // returns the viewport height
$(document).height() // returns the height of the entire document
$(window).scrollTop() // returns the Y position of the document that is at the top of the viewport

Сценарий:

var topRange      = 200,  // measure from the top of the viewport to X pixels down
    edgeMargin    = 20,   // margin above the top or margin from the end of the page
    animationTime = 1200, // time in milliseconds
    contentTop = [];

$(document).ready(function(){

 // Stop animated scroll if the user does something
 $('html,body').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function(e){
  if ( e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel' ){
   $('html,body').stop();
  }
 });

 // Set up content an array of locations
 $('#sidemenu').find('a').each(function(){
  contentTop.push( $( $(this).attr('href') ).offset().top );
 });

 // Animate menu scroll to content
  $('#sidemenu').find('a').click(function(){
   var sel = this,
       newTop = Math.min( contentTop[ $('#sidemenu a').index( $(this) ) ], $(document).height() - $(window).height() ); // get content top or top position if at the document bottom
   $('html,body').stop().animate({ 'scrollTop' : newTop }, animationTime, function(){
    window.location.hash = $(sel).attr('href');
   });
   return false;
 });

 // adjust side menu
 $(window).scroll(function(){
  var winTop = $(window).scrollTop(),
      bodyHt = $(document).height(),
      vpHt = $(window).height() + edgeMargin;  // viewport height + margin
  $.each( contentTop, function(i,loc){
   if ( ( loc > winTop - edgeMargin && ( loc < winTop + topRange || ( winTop + vpHt ) >= bodyHt ) ) ){
    $('#sidemenu li')
     .removeClass('selected')
     .eq(i).addClass('selected');
   }
  });
 });

});
0 голосов
/ 24 мая 2010

Хорошо, спасибо, это помогло мне понять отношения между окном и ссылками, но я не хотел использовать конкретную высоту пикселей, а вместо этого относился к элементам div, которые содержат контент для каждой ссылки.Исходный сайт, который я показал, использует следующее:

function animateMenuLogo(logo, menu) {
    var scrollposition = $(window).scrollTop();
    var top = $("a[name='"+ menu +"']").offset().top;
    var sectionheight = $("a[name='"+ menu +"']").next().outerHeight();

    if (((top-100) < scrollposition) && ((top+sectionheight-200) > scrollposition)) {
        $(logo).fadeIn(500);
        $("a[href='#"+ menu +"']").css({ backgroundColor: "#303e3f", color: "#ffffff" });
        $("a[href='#"+ menu +"']").parent().addClass("current");
    } else {
        $(logo).fadeOut(500);
        $("a[href='#"+ menu +"']").css("background-color","transparent");
        $("a[href='#"+ menu +"']").css("color","#717c7d");$("a[href='#"+ menu +"']").parent().removeClass("current");
    }       
}

Теперь, это только часть кода, и он также контролирует логотип, который появляется справа, но часть, которая меня интересует (и смущает)переменные scrollposition и sectionheight , которые должны позволять меню изменять класс в зависимости от того, виден раздел или нет.

0 голосов
/ 24 мая 2010

Вы можете использовать $(window).scrollTop();, чтобы узнать, как далеко вы ушли от самой вершины.

JS:

$(window).scroll(
    function() {

       var top = 0;
       top = $(window).scrollTop();

       if(top < 500){
         $("a[href='#top']").parent().addClass("current");
         $("a[href='#top']").parent().siblings().removeClass("current");
       }

       if((top >= 500) && (top < 1000)){
         $("a[href='#work']").parent().addClass("current");
         $("a[href='#work']").parent().siblings().removeClass("current");
       }    

       if((top >= 1000) && (top < 1500)){      
         $("a[href='#blog']").parent().addClass("current");
         $("a[href='#blog']").parent().siblings().removeClass("current");
        }   

CSS:

<style type="text/css">
body{
height: 2000px;
}
div#nav{
position: fixed;
top: 170px;
z-index: 10;
}
#nav ul li{
display: block;
margin: 0;
padding: 0;
background: #FFFFFF;
}
#nav ul li a{
backgroundColor: #FFFFFF;
color: #C55500;
}
#nav ul li.current a{
background: none repeat scroll 0 0 #303E3F;
color: #FFFFFF;
}
#nav ul li a{
-moz-border-radius: 5px 5px 5px 5px;
display: block;
line-height: 1;
padding: 10px;
text-align: right;
text-decoration: none;
width: 70px;
}

HTML:

<div id="nav">
  <ul>
    <li><a title="" href="#top">Home</a></li>
    <li><a title="" href="#work">Work</a></li>
    <li><a href="#blog" title="">Blog</a></li>

  </ul>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...