Как выделить нижний ли когда пользователь прокручивает div?

Не могли бы вы рассказать мне, как выделить нижний ли при прокрутке пользователя в div? У меня есть один контейнер div, в котором есть четыре divs. В нижнем колонтитуле у меня также есть четыре li (первый, второй, третий, четвертый). Я хочу выбрать li (фон станет красным), когда пользователь прокручивает соответственно div.

Пример

Когда код запускается, следует выбрать первый li, его фон станет красным, потому что первый div находится в порт представления. Если пользователь прокручивает и перемещается во второй div, следует выбрать второй li. И так далее.

Я так пробовал

https://jsbin.com/giwizufotu/edit?html,css,js,output

(function(){
  'use strict';
  $(function(){
    $( "#container" ).scroll(function() {
      console.log('scrlling');
      if (elementInViewport2($('#first'))) {
        // The element is visible, do something
        console.log('first visible')
    } else {
         console.log('second visible')
    }
    });
  })

  function elementInViewport2(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top < (window.pageYOffset + window.innerHeight) &&
    left < (window.pageXOffset + window.innerWidth) &&
    (top + height) > window.pageYOffset &&
    (left + width) > window.pageXOffset
  );
}

})()

Я не хочу использовать плагин

Ответ 1

https://jsbin.com/borohoheji/edit?html,css,js,console,output

Посмотрите, что я сделал, проверяя, является ли элемент видимым с помощью .is(':visible')

Вы можете работать оттуда и делать именно то, что хотите

Ответ 2

Измените свой код на:

    (function(){
  'use strict';
  $(function(){
    $( "#container" ).scroll(function() {
      console.log('scrlling');
      if (elementInViewport($('#first'))) {
    // The element is visible, do something
        console.log('first visible')
    } else {
         console.log('second visible')
    }
    });
    $( "#container >div" ).hover(
      function() {
        $(this).css('color', 'yellow');
      });
  })

Ответ 3

Сначала сделайте следующее:

  • предоставить всем текстовым divs имя класса, например 'para', чтобы сделать их более легко выбираемыми в виде коллекции.
  • установите директиву ul.fC li.active {...} в вашей таблице стилей, чтобы дать желаемый визуальный эффект.

Тогда:

(function() {
    'use strict';
    $(function() {
        var $container = $("#container"),
            $paras = $container.children(".para"), // the four text divs.
            $listElements = $(".footer ul.fC li"), // the four li elements in the footer.
            oldIndex = -1;
        $container.scroll(function() {
            var index = $paras.index($paras.filter(visibleY).eq(0)); // position of the first visible text div.
            if(index !== oldIndex) { // avoid unnecessary work
                $listElements.eq(oldIndex).removeClass('active'); // remove highlight
                $listElements.eq(index).addClass('active'); // add highlight
                oldIndex = index; // remember index for next event turn
            }
        }).trigger('scroll');
        function visibleY() {
            // based on http://stackoverflow.com/a/21627295/3478010
            var el = this; // because function is called as a .filter() callback.
            var rect = el.getBoundingClientRect(), 
                top = rect.top, 
                height = rect.height, 
                el = el.parentNode;
            do {
                rect = el.getBoundingClientRect();
                if (top <= rect.bottom === false) return false;
                // Check if the element is out of view due to a container scrolling
                if ((top + height) <= rect.top) return false
                el = el.parentNode;
            } while (el != document.body);
            // Check its within the document viewport
            return top <= document.documentElement.clientHeight;
        };
    });
})();

Как написано выше, изменение стиля произойдет в ответ на пары, выходящие/входящие в верхний край контейнера.

Поведение может быть изменено для ответа на пары, выходящие/входящие в нижний край контейнера, путем замены:

var index = $paras.index($paras.filter(visibleY).eq(0)); // position of the first visible para.

с:

var index = $paras.index($paras.filter(visibleY).last()); // position of the last visible para.

Выберите то, что более желательно.