При появлении на экране браузера блока div (их несколько) вызывать ajax

Господа, приветствую.

Дано: на странице несколько блоков вида <div id="idXXX"></div>

Задача: при прокрутке страницы , если блок в видимой пользователю части экрана браузера - вызывать скрипт ajax (помечать прочитанным)

Пытаюсь это решить с помощью jquery, не могу победить :( Буду рад помощи, заранее спасибо.

В идеале еще бы так, чтобы второй раз не вызывалась одна и та же функция, т.е. чтобы срабатывало для каждого блока один раз

Наброски:

 function inWindow(s)
    {
    var scrollTop = $(window).scrollTop();
    var windowHeight = $(window).height();
    var currentEls = $(s);
    var ids=s;
    var offset = currentEls.offset();
    if(scrollTop <= offset.top && (currentEls.height() + offset.top) < (scrollTop + windowHeight))
      {
      /*
      $.ajax({
           url:  "status.php?admin='.$admin.'&id=" + ids + ""  // не работает, не вставляет ids
          });
      */
      console.log("Блок "+ids+" в области видимости");
      }
    }

  $(document).scroll(function ()
    {
    inWindow("#id1")
    });
  $(document).scroll(function ()
    {
    inWindow("#id2")
    });
  $(document).scroll(function ()
    {
    inWindow("#id3")
    });
  $(document).scroll(function ()
    {
    inWindow("#id4")
    });
  $(document).scroll(function ()
    {
    inWindow("#id5")
    });
  
.active
  {
  height:300px;
  background-color:red;
  margin:10px;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="id1" class="active"></div>

<div id="id2" class="active"></div>

<div id="id3" class="active"></div>

<div id="id4" class="active"></div>

<div id="id5" class="active"></div>


Ответы (1 шт):

Автор решения: De.Minov

Объяснения в комментах к коду

let of = $(window).height() / 2, // Отступ, в данным случае считает от центра экрана
    el = $('.active'), // Какие блоки учитывать
    cur = false; // Тут храним блок в скролле, чтобы срабатывало один раз

$(window).on('scroll', function() { // при скролле..
  let sY = $(this).scrollTop(); // получаем текущею позицию скролла
  el.each(function() { // проходим по ВСЕМ блокам которые нужно учитывать
    let el = $(this); // запоминаем его, чтобы не обращаться к нему
    
    // Тут проверяем, входил ли позиция скролла - отступ в границу блока.
    if(el.position().top - of <= sY
    && el.position().top + el.outerHeight() - of > sY) { // если да, то
      if(cur !== el.attr('id')) { // проверяем является ли этот блок тем, что был ранее в записи, если нет, то
        cur = el.attr('id'); // Сохраняем его (НЕ УДАЛЯТЬ)
        el.css('background', 'green'); // Для демо, мы показываем его зелёным
        console.info(el.attr('id')); // И выводим его ID в консоль.
        // Вместо кода выше, нужно оказать ваш AJAX запрос.
      }
    } else { // Если скролл не на границе
      if(cur === el.attr('id')) { // Проверим является ли он тем, что в записи
        el.css('background', ''); // удалим у него фон
        console.info('ушли с '+cur); // покажем что мы с него ушли
        // Тут может быть какое-то обратное действие, допустим снять класс с объекта который покинул область видимости.
      }
    }
  });
});
.as-console-wrapper {max-height: 42px !important;} /* для демо */

.active {
  height: 300px;
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>


<div id="id1" class="active"></div>
<div id="id2" class="active"></div>
<div id="id3" class="active"></div>
<div id="id4" class="active"></div>
<div id="id5" class="active"></div>

Советую чтобы между блоками .active не было отступов вообще.

→ Ссылка