Попытка добавить подсветку навигации при прокрутке с помощью javascript/jQuery. Что-то не так в определении высоты элементов

Я работаю над прокручиваемой страницей портфолио для Free Code Camp и пытаюсь добавить подсветку навигации. Под этим я подразумеваю, что хотел бы сделать так, чтобы после прокрутки вверху раздела (т. е. от раздела «домой» к разделу «о») навигационная ссылка, соответствующая этому разделу, должна была выделиться. Эту часть я на самом деле понял по большей части. Однако есть ошибка, которую я не могу понять. Переход от раздела «Портфолио» к разделу «Контакты» выделяется в навигации, прежде чем я перехожу к фактическому разделу. Может ли кто-нибудь из вас понять, почему это так?

У меня есть ощущение, что это как-то связано с тем, что я использую функцию .innerHeight в javascript, но я не уверен.

Вот соответствующий javascript, и внизу у меня будет ссылка на codepen.

    $(document).ready(function() {

      var navHeight = $('nav').innerHeight();
      var componentEnd = [];


      $('.component').each(function(){
        componentEnd.push($(this).offset().top + $(this).innerHeight() - navHeight);
      });

      $(document).on('scroll', function() {
        var pos = $(document).scrollTop();

        for (var i = 0; i < componentEnd.length; i++) {
          if (pos <= componentEnd[i] ) {
            var index = i;
              break;
          }
        }

        $('.navbar-nav li')
          .removeClass('nav-active')
          .eq(index)
          .addClass('nav-active');
      });
    });

Страница портфолио — Codepen

Если у кого-то из вас есть мысли, буду очень признателен! Я работаю над этим некоторое время.


person Michael Waara    schedule 10.03.2017    source источник
comment
Какую ОС и браузер вы используете? Кажется, я не могу воспроизвести это на OS X в Chrome или Firefox. Хотя в FF он не выделяет контактную навигацию, если вы прокручиваете ее до конца. Вы взглянули на externalHeight для jQuery? api.jquery.com/outerheight   -  person Pango    schedule 10.03.2017
comment
Эй, выглядит великолепно — я думаю, проблема возникает, если вы настраиваете ширину окна браузера (технически области просмотра) — отзывчивость изменяет высоту элементов — потому что вы захватываете innerHeights на готове, это больше не точно. вы можете зафиксировать событие изменения размера окна и переоценить внутренние высоты.   -  person luckyape    schedule 10.03.2017
comment
@Pango Как вы думаете, это проблема кроссбраузерной совместимости?   -  person Michael Waara    schedule 10.03.2017
comment
Я не был уверен, я просто не мог заставить его воспроизвести, поэтому я пытался выяснить, правильно ли я понял проблему. Хотя, похоже, это было решено!   -  person Pango    schedule 10.03.2017


Ответы (1)


Проверьте это: зафиксировав событие изменения размера и пересчитав высоту, проблема исчезнет.

$(document).ready(function () {

  var navHeight = $('nav').innerHeight();

  $('.navbar-nav li a').click(function (event) {
    $('.navbar-collapse').collapse('hide');
  });

  $('a[href^="#"]').on('click', function (e) {
    e.preventDefault();

    var target = this.hash;
    var $target = $(target);

    $('html, body').stop().animate({
      'scrollTop': ($target.offset().top - navHeight)
    }, 900, 'swing');
  });

  var componentEnd = [];

  // Create function to run heights whenever required
  function getHeights() {         
    componentEnd = []; // empty old height
    $('.component').each(function(){
      componentEnd.push($(this).offset().top + $(this).innerHeight() - navHeight);
    }); 
  }
  // run heights initially 
  getHeights();

  //capture window rezise
  $( window ).resize(getHeights);

  $(document).on('scroll', function() {
    var pos = $(document).scrollTop();

    for (var i = 0; i < componentEnd.length; i++) {
      if (pos <= componentEnd[i] ) {
        var index = i;
        break;
      }
    }

    $('.navbar-nav li')
      .removeClass('nav-active')
      .eq(index)
      .addClass('nav-active');
  });
});

https://codepen.io/anon/pen/YZZZOw

Вы, наверное, заметили, что проблема возникает после изменения размера окна, которое влияет на высоту ваших элементов. Захватив изменение размера и поместив код innerHeight в вызываемую функцию, мы можем решить проблему.

person luckyape    schedule 10.03.2017