2014-02-14 3 views
1

Я пытаюсь сделать вспомогательное навигационное меню для изменения фиксированной позиции после того, как пользователь прокрутил вниз 200 пикселей от вершины. Он работает, но он очень глючит, например, когда пользователь прокручивается назад, он не всегда возвращается в исходное положение и т. Д. Я не сильно разбираюсь в javascript/jquery, но я думал, что это будет просто сделать. Что мне не хватает?jQuery scrollTop be buggy

Вот мой fidde: http://jsfiddle.net/visevo/bx67Z/

и фрагмент кода:

(function() { 
    console.log("hello"); 
    var target = $('#side-nav'); 
    var scrollDis = 200; 
    var reset = 20; 
    var speed = 500; 
    $(window).scroll(function() { 
     console.log($(window).scrollTop()); 
     if($(window).scrollTop() > scrollDis) { 

      $(target).animate({ 
       top: reset + 'px' 
      }, speed); 
     } else { 
      $(target).animate({ 
       top: scrollDis + 'px' 
      }, speed); 
     } 
    }); 
})(); 
+0

Scrolltop глючит в IE 7/8 :( –

+0

Где сделал Бэкон ipsum dolor исходит из? Это ваша собственная вещь? –

+0

Кроме того, причина, по которой она не возвращается к исходной позиции, заключается в том, что ваш css имеет исходный верх, как 100px, но когда вы его сбросите, вы сбросите его до 200px. –

ответ

1

http://jsfiddle.net/bx67Z/3/

Я просто добавил .stop() перед .animate(), и он работает намного лучше уже.

 $(target).stop().animate({ 
      top: reset + 'px' 
     }, speed); 
    } else { 
     $(target).stop().animate({ 
      top: scrollDis + 'px' 
     }, speed); 

Вы также можете использовать .stop(true)

http://jsfiddle.net/bx67Z/5/

 $(target).stop(true).animate({ 
      top: reset + 'px' 
     }, speed); 
    } else { 
     $(target).stop(true).animate({ 
      top: scrollDis + 'px' 
     }, speed); 

Вы также можете использовать .stop(true, true)

http://jsfiddle.net/bx67Z/4/

 $(target).stop(true, true).animate({ 
      top: reset + 'px' 
     }, speed); 
    } else { 
     $(target).stop(true, true).animate({ 
      top: scrollDis + 'px' 
     }, speed); 

Так что причина .stop(true) работает так хорошо, что она очищает очередь анимации. Причина, по которой вы были «багги», состоит в том, что на каждом прокрутке очередь анимации «пузырялась», поэтому потребовалось много времени, чтобы она дошла до точки, где она вернется в исходное положение.

Для получения информации о .stop() смотрите здесь http://api.jquery.com/stop

+0

Стоп (true, true) заставляет анимацию пропустить, прокручивая ее быстро, по крайней мере, на моей ОС (win8) с помощью chrome или firefox. Я думаю, что .stop() без параметров работает наилучшим образом – visevo

+1

Я закончил использование .stop (true), потому что второй параметр вызывает пропущенную анимацию. Сейчас работает безупречно. Благодаря! – visevo

2

Как насчет немного CSS и JQuery как ??

Что я сделал, добавлен переход к side-nav, чтобы оживить его и исправить ваши js, чтобы просто изменить его css. Вы можете установить, как быстро он перемещается, изменяя время перехода.

FIDDLE

#side-nav { 
    position: fixed; 
    top: 100px; 
    left: 10px; 
    width: 100px; 
    background: #ccc; 
    -webkit-transition:all 0.5s ease-in-out; 
} 

(function() { 
    var target = $('#side-nav'); 
    var scrollDis = 100; 
    var reset = 20; 
    var speed = 500; 
    $(window).scroll(function() { 
     if ($(this).scrollTop() >= scrollDis) { 

      target.css("top", reset); 
     } else { 
      target.css("top", scrollDis); 
     } 
    }); 
})(); 

ПРИМЕЧАНИЕ: Когда вы кэшировать объект JQuery, как этот

var target = $("#side-nav"); 

Вам не нужно использовать $ снова вокруг этой переменной.

+2

Объединение jQuery и CSS в анимации открывает вихрь в континууме стекового пространства и вызывает ненужную связь между разработчиков и дизайнеров. Такое поведение по своей сути опасно и не рекомендуется. –

+0

Действительно? С каких пор дизайнеры не могут обрабатывать jquery? Кроме того, на мой взгляд, вы должны использовать css столько, сколько сможете. –

+0

Это работает, но Джефф Дэвис прав, и он также оставляет IE <10, и я должен поддерживать минимум 8. Спасибо за ваш ответ, хотя! – visevo

2

Поскольку я комментирую повсюду я должен, вероятно, на самом деле внести свой вклад в ответ.

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

(function() { 
    console.log("hello"); 
    var target = $('#side-nav'); 
    var scrollDis = 200; 
    var reset = 20; 
    var speed = 500; 
    var passedPosition = false; 
    var bolMoving = false; 
    $(window).scroll(function() { 
     if (bolMoving) return; // Cancel double calls. 
     console.log($(window).scrollTop()); 
     if (($(window).scrollTop() > scrollDis) && !passedPosition) { 
      bolMoving = true; // 
      $(target).animate({ 
       top: reset + 'px' 
      }, speed, function() { bolMoving = false; passedPosition = true; }); 
     } else if (passedPosition && $(window).scrollTop() <= scrollDis) { 
      bolMoving = true; 
      $(target).animate({ 
       top: scrollDis + 'px' 
      }, speed, function() { bolMoving = false; passedPosition = false; }); 
     } 
    }); 
})(); 

http://jsfiddle.net/bx67Z/12/