Обнаружение, когда пользователь прокручивает до конца div с помощью jQuery

219

У меня есть блок div (называемый поток) с переменным количеством содержимого внутри. Для этого divbox установлено переполнение auto.

Теперь, что я пытаюсь сделать, это когда прокрутить использование до нижней части этого DIV-блока, загрузить больше контента на страницу, я знаю, как это сделать (загрузить контент), но я не знаю, как определить, когда пользователь прокрутил до конца тега div? Если бы я хотел сделать это для всей страницы, я бы взял .scrollTop и вычел это из .height.

Но я не могу сделать это здесь?

Я попытался взять .scrollTop из потока, а затем обернуть все содержимое внутри div, называемого внутренним, но если я возьму innerHeight потока, он возвращает 564px (div установлен в 500 как высота) и высоту 'innner' он возвращает 1064, и прокрутка, когда в нижней части div говорит 564.

Что я могу сделать?

EAX
источник

Ответы:

422

Есть несколько свойств / методов, которые вы можете использовать:

$().scrollTop()//how much has been scrolled
$().innerHeight()// inner height of the element
DOMElement.scrollHeight//height of the content of the element

Таким образом, вы можете взять сумму первых двух свойств, а когда она равна последнему свойству, вы достигли конца:

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
            alert('end reached');
        }
    })
});

http://jsfiddle.net/doktormolle/w7X9N/

Изменить: я обновил «привязать» к «в» согласно:

Начиная с jQuery 1.7, метод .on () является предпочтительным методом для прикрепления обработчиков событий к документу.

Dr.Molle
источник
2
Он выполнит привязку, когда DOM будет готов убедиться, что элемент # flux уже доступен.
Доктор Молл
1
Вы должны обновить свой ответ, используя ON вместо bind, bind устарел в пользу On
ncubica
34
Примечание. Когда пользователь использует уровни масштабирования в своем браузере, это может не сработать. Zoom заставляет innerHeight()сообщать десятичные числа. В случае уменьшения масштаба пользователя сумма scrollTop()и innerHeight()всегда будет, по крайней мере, на долю меньше scrollHeight. В итоге я добавил буферную зону размером 20 пикселей. В результате условным было if(el.scrollTop() + el.innerHeight() >= el[0].scrollHeight - 20)где elравно $(this).
Ник
1
Это лучший ответ, который когда-либо работал для меня очень хорошо. Спасибо
Ашиш Ядав
1
Это больше не работает, не могли бы вы подтвердить, почему это не работает, спасибо
Умайр Шах
51

Я нашел решение, которое, когда вы прокручиваете свое окно и конец деления, показанного снизу, выдает предупреждение.

$(window).bind('scroll', function() {
    if($(window).scrollTop() >= $('.posts').offset().top + $('.posts').outerHeight() - window.innerHeight) {
        alert('end reached');
    }
});

В этом примере, если вы прокрутите вниз, когда div ( .posts) завершит работу, вы получите предупреждение.

Эхсан Агаи
источник
спасибо за это, но как я могу оживить div, когда он достигнет дна этого div? также, когда вы прокручиваете вверх, обнаруживаете вершину этого div, а затем анимируете также. Так же, как здесь, на этом сайте lazada.com.ph/apple поведение боковой панели Надеюсь, вы можете помочь мне :)
Алисса Рейес
Это работает как волшебство, но проблема в том, что предупреждение выполняется два раза, поэтому если у вас есть вызов функции внутри, он будет выполнен два раза
Afaf
1
@ 1616 У меня есть переменная, var running = falseобъявленная до этого. Внутри условно я проверяю if(!running) { running = true; // and continue logic } Так он вызывается только один раз! Когда AJAX завершится, установитеrunning = false;
Джейкоб Раккуя
1
Речь идет об окне, но вопрос о div.
Александр Волков
42

Хотя вопрос был задан 5,5 лет назад, он все же более чем актуален в современном контексте UI / UX. И я хотел бы добавить свои два цента.

var element = document.getElementById('flux');
if (element.scrollHeight - element.scrollTop === element.clientHeight)
    {
        // element is at the end of its scroll, load more content
    }

Источник: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Determine_if_an_element_has_been_totally_scrolled

Некоторые элементы не позволят вам прокрутить всю высоту элемента. В этих случаях вы можете использовать:

var element = docuement.getElementById('flux');
if (element.offsetHeight + element.scrollTop === element.scrollHeight) {
  // element is at the end of its scroll, load more content
}
мышление
источник
2
Это решение, которое вы ищете, если вы не используете jQuery.
Петтер Петтерссон
Есть обработчик событий?
Александр Волков
@AlexanderVolkov onscroll это связанное событие.
Мышление
9

Просто дополнительная заметка, когда я нашел это, когда искал решение для фиксированного div, который я хочу прокрутить. Для моего сценария я обнаружил, что предпочтительнее учитывать отступы на div, чтобы я мог точно достичь конца. Итак, расширяя ответ @ Dr.Molle, я добавляю следующее

$('#flux').bind('scroll', function() {
    var scrollPosition = $(this).scrollTop() + $(this).outerHeight();
    var divTotalHeight = $(this)[0].scrollHeight 
                          + parseInt($(this).css('padding-top'), 10) 
                          + parseInt($(this).css('padding-bottom'), 10)
                          + parseInt($(this).css('border-top-width'), 10)
                          + parseInt($(this).css('border-bottom-width'), 10);

    if( scrollPosition == divTotalHeight )
    {
      alert('end reached');
    }
  });

Это даст вам точное местоположение, включая отступы и границы

Александр Миллар
источник
7

это работает для меня, хотя

$(window).scroll(function() {
  if ($(window).scrollTop() >= (($(document).height() - $(window).height()) - $('#divID').innerHeight())) {
    console.log('div reached');
  }
});
Рикардо Ривас
источник
3

Если вам нужно использовать это в div, у которого overflow-y скрыт или прокручивается, вам может понадобиться нечто подобное.

if ($('#element').prop('scrollHeight') - $('#element').scrollTop() <= Math.ceil($('#element').height())) {
    at_bottom = true;
}

Я обнаружил, что ceil был необходим, потому что prop scrollHeight, кажется, округляется, или, возможно, какая-то другая причина, заставляющая его отключаться менее чем на 1.

Гусь
источник
3

Если вы не используете функцию Math.round (), решение, предложенное Dr.Molle, не будет работать в некоторых случаях, когда окно браузера имеет масштаб.

Например, $ (this) .scrollTop () + $ (this) .innerHeight () = 600

$ (this) [0] .scrollHeight yields = 599.99998

600> = 599,99999.

Вот правильный код:

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if(Math.round($(this).scrollTop() + $(this).innerHeight(), 10) >= Math.round($(this)[0].scrollHeight, 10)) {
            alert('end reached');
        }
    })
});

Вы также можете добавить несколько дополнительных пикселей поля, если вам не нужно строгое условие

var margin = 4

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if(Math.round($(this).scrollTop() + $(this).innerHeight(), 10) >= Math.round($(this)[0].scrollHeight, 10) - margin) {
            alert('end reached');
        }
    })
});
Павел Гавриленко
источник
2

В простом использовании DOM вы можете проверить состояние

element.scrollTop + element.clientHeight == element.scrollHeight

если это правда, то вы достигли конца.

Луай Алош
источник
1

Если кто-то получает scrollHeightкак undefined, то выберите 1-й подэлемент элемента:mob_top_menu[0].scrollHeight

Starwave
источник
1

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

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

С уважением.

<style type="text/css">
    .fixed_Bot {    
            position: fixed;     
            bottom: 24px;    
        }     
</style>

<script type="text/javascript">
    $(document).ready(function () {
        var sidebarheight = $('#index').height();
        var windowheight = $(window).height();


        $(window).scroll(function () {
            var scrollTop = $(window).scrollTop();

            if (scrollTop >= sidebarheight - windowheight){
                $('#index').addClass('fixed_Bot');
            }
            else {
                $('#index').removeClass('fixed_Bot');
            }                   
        });
    });

</script>
Израиль Чапа
источник
1

Хотя это было задано почти 6 лет назад, еще горячей темой в UX-дизайне, вот демонстрационный фрагмент, если любой новичок хотел использовать

$(function() {

  /* this is only for demonstration purpose */
  var t = $('.posts').html(),
    c = 1,
    scroll_enabled = true;

  function load_ajax() {

    /* call ajax here... on success enable scroll  */
    $('.posts').append('<h4>' + (++c) + ' </h4>' + t);

    /*again enable loading on scroll... */
    scroll_enabled = true;

  }


  $(window).bind('scroll', function() {
    if (scroll_enabled) {

      /* if 90% scrolled */
    if($(window).scrollTop() >= ($('.posts').offset().top + $('.posts').outerHeight()-window.innerHeight)*0.9) {

        /* load ajax content */
        scroll_enabled = false;  
        load_ajax();
      }

    }

  });

});
h4 {
  color: red;
  font-size: 36px;
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="posts">
  Lorem ipsum dolor sit amet  Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut libero Curabitur id <br> Dui pretium hendrerit
  sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut libero Curabitur id <br>  Dui pretium hendrerit sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut
  libero Curabitur id <br> Dui pretium hendrerit sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet
  lacus Donec <br> Ut ut libero Curabitur id <br> Dui pretium hendrerit sapien Pellentesque
</div>

Акшай Хегде
источник
0

Ребята, это решение проблемы масштабирования, оно работает со всеми уровнями масштабирования, если вам это нужно:

if ( Math.abs(elem.offset().top) + elem.height() + elem.offset().top >= elem.outerHeight() ) {
                    console.log("bottom");
                    // We're at the bottom!
                }
            });
        }
Лиад Ливнат
источник
0
$(window).on("scroll", function() {
    //get height of the (browser) window aka viewport
    var scrollHeight = $(document).height();
    // get height of the document 
    var scrollPosition = $(window).height() + $(window).scrollTop();
    if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
        // code to run when scroll to bottom of the page
    }
});

Это код на GitHub.

aki_sud
источник
-1

Вот другая версия.

Код клавиши - это функция scroller (), которая принимает ввод как высоту div, содержащего секцию прокрутки, используя overflow: scroll. Это приблизительно 5 пикселей сверху или 10 пикселей снизу как сверху или снизу. В противном случае это слишком чувствительно. Кажется, 10px - это минимум. Вы увидите, что это добавляет 10 к высоте div, чтобы получить высоту дна. Я предполагаю, что 5px может работать, я не тестировал экстенсивно. YMMV. scrollHeight возвращает высоту внутренней области прокрутки, а не отображаемую высоту div, которая в данном случае составляет 400 пикселей.

<?php

$scrolling_area_height=400;
echo '
<script type="text/javascript">
          function scroller(ourheight) {
            var ourtop=document.getElementById(\'scrolling_area\').scrollTop;
            if (ourtop > (ourheight-\''.($scrolling_area_height+10).'\')) {
                alert(\'at the bottom; ourtop:\'+ourtop+\' ourheight:\'+ourheight);
            }
            if (ourtop <= (5)) {
                alert(\'Reached the top\');
            }
          }
</script>

<style type="text/css">
.scroller { 
            display:block;
            float:left;
            top:10px;
            left:10px;
            height:'.$scrolling_area_height.';
            border:1px solid red;
            width:200px;
            overflow:scroll; 
        }
</style>

$content="your content here";

<div id="scrolling_area" class="scroller">
onscroll="var ourheight=document.getElementById(\'scrolling_area\').scrollHeight;
        scroller(ourheight);"
        >'.$content.'
</div>';

?>
Джон Островик
источник
1
-1, потому что генерирование кода javascript + css из php - плохая практика (трудно поддерживать, нет возможности повторного использования, нет оптимизации сайта и т. Д.). Кроме того, как отметил @Alexander Millar, смещение в 10px можно исправить, принимая во внимание отступы. Любой, кто рассматривает возможность использования этого кода, должен подумать дважды ...
Капитеин Витбаард