jQuery - добавление класса в / после определенной точки прокрутки с содержимым переменной длины выше - PullRequest
4 голосов
/ 20 августа 2010

Довольно плохо знакомы с jQuery и JavaScript в целом.Я смоделировал пример моей проблемы на http://jsbin.com/alibi3/2/ - с объяснением ниже.

У меня есть div, который после того, как пользователь прокручивает определенную точку на странице, назначаетсякласс «исправлено», поэтому он следует за пользователем вниз по странице.Это прекрасно работает само по себе.

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

Как мне сказать моей функции добавления фиксированных классов, что div был показан / скрыт, и настроить точку, в которой «фиксированный»класс добавлен?

Спасибо.

HTML:

<div id="drawer">
    <a href="#">Click here to toggle drawer</a>
    <p id="drawercontents">Here is the stuff in the drawer; hidden by default.</p>
</div>
<div id="article">
    blah, blah...
</div>
<div id="nav">
    This should follow down the page once we scroll past the start of the article,
    and 'stick' back in place when we are back at the top.
</div>

CSS:

  #article {
    width: 400px;
    float: left;
    margin-right: 20px;
    padding: 20px;
    background: #eee;
  }
  #nav {
    width: 200px;
    float: left;
    background: #ff0;
    padding: 20px;
  }
  #drawer {
    width: 660px;
    padding: 20px;
    color:#fff;
    background: #000;
    margin-bottom: 10px;
  }
  .fixed { position: fixed; left: 460px; top: 0px; }

JavaScript:

$(document).ready(function() {
  $('#drawercontents').hide();

  $('#drawer a').click(function(e){
    e.preventDefault();
    $('#drawercontents').toggle('fast');
  });

  var top =$('#nav').offset().top - parseFloat($('#nav').css('marginTop').replace(/auto/, 0));
  $(window).scroll(function () {
    // what is the y position of the scroll?
    var y = $(window).scrollTop();    
    // whether that's below the start of article?
    if (y >= top) {
      // if so, add the fixed class
      $('#nav').addClass('fixed');
    } else {
      // otherwise, remove it
      $('#nav').removeClass('fixed');
    }
  });
});

Ответы [ 2 ]

2 голосов
/ 20 августа 2010

Всякий раз, когда вы делаете что-то, что изменяет базовую позицию этого «фиксированного» div, вам необходимо повторно сделать снимок его базовой позиции.

Например, в вашем демонстрационном коде пересчитайте верхнюю часть внутри toggle() вызов.
См. Модифицированный код ниже или посмотрите его в действии на http://jsbin.com/alibi3/8.

var GblTop;

function GetVertOffset (srchStr)
{
    GblTop = $(srchStr).offset().top - parseFloat($(srchStr).css('marginTop').replace(/auto/, 0));
}


$(document).ready(function ()
{
    $('#drawercontents').hide();

    $('#drawer a').click (function (e)
    {
        e.preventDefault();
        $('#drawercontents').toggle('fast', function() {GetVertOffset ('#nav'); } );
    });


    GetVertOffset ('#nav');     //-- Sets GblTop

    $(window).scroll (function ()
    {
        // what is the y position of the scroll?
        var y = $(window).scrollTop();
        // whether that's below the start of article?
        if (y >= GblTop)
        {
            // if so, add the fixed class
            $('#nav').addClass('fixed');
        }
        else
        {
            // otherwise, remove it
            $('#nav').removeClass('fixed');
        }
    });

});
0 голосов
/ 20 августа 2010

Разобрался сам!На случай, если кто-то еще столкнется с такой же проблемой и столкнется с этим, вот мой пересмотренный код и лучшее (хотя и дилетантское) объяснение того, что я сделал:*

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<!--[if IE]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
  article, aside, figure, footer, header, hgroup, 
  menu, nav, section { display: block; }
  body { margin: 0; padding: 0; }
  #article { width: 400px; height: 1000px; float: left; margin-right: 20px; padding: 20px; background: #eee; }
  #nav { width: 200px; float: left; background: #ff0; padding: 20px; }
  #drawer { width: 660px; padding: 20px; color:#fff; background: #000; margin-bottom: 10px; }
  .fixed { position: fixed; left: 460px; top: 0px; }
</style>
</head>
<body>
  <div id="drawer">
    <a href="#">Click here to toggle drawer</a>
    <p id="drawercontents">Here is the stuff in the drawer. It is hidden by default. When it is shown there is a problem with the nav jumping to the top of the page when we scroll.</p>
  </div>
  <div id="article">
    <h2>This is a long article!</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit pellentesque sed egestas id, iaculis ut erat. Praesent ut neque vel dolor lacinia eleifend at sit amet sem, etc etc</p>

    <p>Div height has been set to 1000px to force scrolling without adding too much filler text</p>
  </div> <!-- end article -->
    <div id="nav">
     This should follow down the page once we scroll past the start of the article, and 'stick' back in place when we are back at the top.
  </div>
</body>
</html>​​

Рабочий пример для JS Bin - http://jsbin.com/alibi3/9

top задан как глобальная переменная, поэтому его можно использовать между функциями.Сначала он устанавливается на загрузку документа, затем он переопределяется всякий раз, когда запускается функция переключения ящика $('#drawer a').click(function(e).

Так что теперь, когда запускается $(window).scroll, он имеет правильное значение top дляработать и вести себя так, как я хочу.

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