Я создаю систему разбиения на страницы (вроде Facebook), где контент загружается, когда пользователь прокручивается вниз. Я предполагаю, что лучший способ сделать это - найти, когда пользователь находится в нижней части страницы, и запустить запрос ajax для загрузки большего количества сообщений.
Единственная проблема заключается в том, что я не знаю, как проверить, прокручивается ли пользователь в нижней части страницы с помощью jQuery. Любые идеи?
Мне нужно найти способ проверить, когда пользователь прокручивается в нижней части страницы с помощью jQuery.
Ответ 1
Используйте .scroll()
событие window
, например:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("bottom!");
}
});
Вы можете протестировать его здесь, это занимает верхний прокрутки окна, поэтому, насколько он прокручивается вниз, добавляет высоту видимого окно и проверяет, соответствует ли это высоте общего содержимого (document
). Если вы хотите вместо этого проверить, находится ли пользователь в нижней части, он выглядит примерно так:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
alert("near bottom!");
}
});
Вы можете протестировать эту версию здесь, просто настройте этот 100
на любой пиксель снизу, на который вы хотите включить.
Ответ 2
Ответ Nick Craver отлично работает, избавляет от проблемы, что значение $(document).height()
зависит от браузера.
Чтобы он работал на всех браузерах, используйте эту функцию из James Padolsey:
function getDocHeight() {
var D = document;
return Math.max(
D.body.scrollHeight, D.documentElement.scrollHeight,
D.body.offsetHeight, D.documentElement.offsetHeight,
D.body.clientHeight, D.documentElement.clientHeight
);
}
вместо $(document).height()
, так что конечный код:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == getDocHeight()) {
alert("bottom!");
}
});
Ответ 3
Я не совсем уверен, почему это еще не опубликовано, но согласно документации из MDN, самый простой способ - использовать собственные свойства javascript:
element.scrollHeight - element.scrollTop === element.clientHeight
Возвращает true, когда вы находитесь в нижней части любого прокручиваемого элемента. Поэтому просто используя javascript:
element.addEventListener('scroll', function(event)
{
var element = event.target;
if (element.scrollHeight - element.scrollTop === element.clientHeight)
{
console.log('scrolled');
}
});
scrollHeight
имеют широкую поддержку в браузерах, то есть 8, чтобы быть более точными, а clientHeight
и scrollTop
поддерживаются всеми. Даже то есть 6. Это должно быть безопасным для браузера.
Ответ 4
Для тех, кто использует решение Ник и получает повторные предупреждения/события, вы можете добавить строку кода выше примера предупреждения:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).unbind('scroll');
alert("near bottom!");
}
});
Это означает, что код будет срабатывать только в первый раз, когда вы находитесь в пределах 100 пикселей от нижней части документа. Он не будет повторяться, если вы прокрутите резервную копию, а затем отпустите, что может быть полезно или не может быть полезно в зависимости от того, для чего вы используете код Nick.
Ответ 5
В дополнение к превосходному принятому ответу от Nick Craver вы можете дросселировать событие прокрутки так, чтобы оно не запускалось так часто, таким образом увеличение производительности браузера:
var _throttleTimer = null;
var _throttleDelay = 100;
var $window = $(window);
var $document = $(document);
$document.ready(function () {
$window
.off('scroll', ScrollHandler)
.on('scroll', ScrollHandler);
});
function ScrollHandler(e) {
//throttle event:
clearTimeout(_throttleTimer);
_throttleTimer = setTimeout(function () {
console.log('scroll');
//do work
if ($window.scrollTop() + $window.height() > $document.height() - 100) {
alert("near bottom!");
}
}, _throttleDelay);
}
Ответ 6
Ответ Nick Craver должен быть слегка изменен для работы с iOS 6 Safari Mobile и должен быть:
$(window).scroll(function() {
if($(window).scrollTop() + window.innerHeight == $(document).height()) {
alert("bottom!");
}
});
Изменение $(window).height() на window.innerHeight должно выполняться, потому что, когда адресная строка скрыта, дополнительные 60 пикселей добавляются к высоте окна, но используя $(window).height()
отражает не это изменение, а использование window.innerHeight
делает.
Примечание. Свойство window.innerHeight
также включает горизонтальную высоту полосы прокрутки (если она отображается), в отличие от $(window).height()
, которая не будет включать горизонтальную высоту полосы прокрутки. Это не проблема в Mobile Safari, но может привести к неожиданному поведению в других браузерах или будущих версиях Mobile Safari. Изменение ==
до >=
может исправить это для большинства распространенных случаев использования.
Подробнее о свойстве window.innerHeight
здесь
Ответ 7
Здесь довольно простой подход:
elm.onscroll = function() {
if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) //User has scrolled to the bottom of the element
}
Ответ 8
Вот фрагмент кода, который поможет вам отладить ваш код, я протестировал вышеупомянутые ответы и обнаружил, что они ошибочны. Я тестировал следующие действия в Chrome, IE, Firefox, IPad (Safari). У меня нет других, чтобы проверить...
<script type="text/javascript">
$(function() {
$(window).scroll(function () {
var docElement = $(document)[0].documentElement;
var winElement = $(window)[0];
if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
alert('bottom');
}
});
});
</script>
Может быть более простое решение, но я остановился в точке, где IT WORKED
Если у вас все еще есть проблемы с некоторыми браузерами-изгоями, вот какой код вы можете отлаживать:
<script type="text/javascript">
$(function() {
$(window).scroll(function () {
var docElement = $(document)[0].documentElement;
var details = "";
details += '<b>Document</b><br />';
details += 'clientHeight:' + docElement.clientHeight + '<br />';
details += 'clientTop:' + docElement.clientTop + '<br />';
details += 'offsetHeight:' + docElement.offsetHeight + '<br />';
details += 'offsetParent:' + (docElement.offsetParent == null) + '<br />';
details += 'scrollHeight:' + docElement.scrollHeight + '<br />';
details += 'scrollTop:' + docElement.scrollTop + '<br />';
var winElement = $(window)[0];
details += '<b>Window</b><br />';
details += 'innerHeight:' + winElement.innerHeight + '<br />';
details += 'outerHeight:' + winElement.outerHeight + '<br />';
details += 'pageYOffset:' + winElement.pageYOffset + '<br />';
details += 'screenTop:' + winElement.screenTop + '<br />';
details += 'screenY:' + winElement.screenY + '<br />';
details += 'scrollY:' + winElement.scrollY + '<br />';
details += '<b>End of page</b><br />';
details += 'Test:' + (docElement.scrollHeight - winElement.innerHeight) + '=' + winElement.pageYOffset + '<br />';
details += 'End of Page? ';
if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
details += 'YES';
} else {
details += 'NO';
}
$('#test').html(details);
});
});
</script>
<div id="test" style="position: fixed; left:0; top: 0; z-index: 9999; background-color: #FFFFFF;">
Надеюсь, это немного сэкономит время.
Ответ 9
Это мои два цента:
$('#container_element').scroll( function(){
console.log($(this).scrollTop()+' + '+ $(this).height()+' = '+ ($(this).scrollTop() + $(this).height()) +' _ '+ $(this)[0].scrollHeight );
if($(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight){
console.log('bottom found');
}
});
Ответ 10
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;
Он вычисляет полосу прокрутки расстояния до нижней части элемента.
Равно 0, если полоса прокрутки достигла дна.
Ответ 11
Пожалуйста, проверьте этот ответ
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log("bottom");
}
};
Вы можете сделать footerHeight - document.body.offsetHeight
, чтобы увидеть, находитесь ли вы рядом с нижним колонтитулом или достигли нижнего колонтитула
Ответ 12
Pure JS с кросс-браузер и debouncing (довольно хорошая производительность)
var CheckIfScrollBottom = debouncer(function() {
if(getDocHeight() == getScrollXY()[1] + window.innerHeight) {
console.log('Bottom!');
}
},500);
document.addEventListener('scroll',CheckIfScrollBottom);
function debouncer(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}
function getScrollXY(){var a=0,b=0;return"number"==typeof window.pageYOffset?(b=window.pageYOffset,a=window.pageXOffset):document.body&&(document.body.scrollLeft||document.body.scrollTop)?(b=document.body.scrollTop,a=document.body.scrollLeft):document.documentElement&&(document.documentElement.scrollLeft||document.documentElement.scrollTop)&&(b=document.documentElement.scrollTop,a=document.documentElement.scrollLeft),[a,b]}
function getDocHeight(){var a=document;return Math.max(a.body.scrollHeight,a.documentElement.scrollHeight,a.body.offsetHeight,a.documentElement.offsetHeight,a.body.clientHeight,a.documentElement.clientHeight)}
Демо: http://jsbin.com/geherovena/edit?js,output
PS: Debouncer
, getScrollXY
, getDocHeight
не написано мной
Я просто покажу, как его работа, И как я буду делать
Ответ 13
Nick отвечает на все вопросы, но у вас будут функции, которые повторяются при прокрутке или вообще не будут работать, если пользователь увеличил окно. Я придумал простое исправление только математике. Вокруг первой высоты и работает так же, как предполагалось.
if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){
loadPagination();
$(".go-up").css("display","block").show("slow");
}
Ответ 14
Вы можете попробовать следующий код,
$("#dashboard-scroll").scroll(function(){
var ele = document.getElementById('dashboard-scroll');
if(ele.scrollHeight - ele.scrollTop === ele.clientHeight){
console.log('at the bottom of the scroll');
}
});
Ответ 15
Мое решение в простой JS:
let el=document.getElementById('el');
el.addEventListener('scroll', function(e) {
if (this.scrollHeight - this.scrollTop - this.clientHeight<=0) {
alert('Bottom');
}
});
#el{
width:400px;
height:100px;
overflow-y:scroll;
}
<div id="el">
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
</div>
Ответ 16
Попробуйте это для условия соответствия, если прокрутить до нижнего конца
if ($(this)[0].scrollHeight - $(this).scrollTop() ==
$(this).outerHeight()) {
//code for your custom logic
}
Ответ 17
Все эти решения не работают для меня в Firefox и Chrome, поэтому я использую пользовательские функции из Miles O'Keefe и meder omuraliev вот так:
function getDocHeight()
{
var D = document;
return Math.max(
D.body.scrollHeight, D.documentElement.scrollHeight,
D.body.offsetHeight, D.documentElement.offsetHeight,
D.body.clientHeight, D.documentElement.clientHeight
);
}
function getWindowSize()
{
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return [myWidth, myHeight];
}
$(window).scroll(function()
{
if($(window).scrollTop() + getWindowSize()[1] == getDocHeight())
{
alert("bottom!");
}
});
Ответ 18
Это дает точные результаты при проверке прокручиваемого элемента (т.е. не window
):
// 'element' is a native JS HTMLElement
if ( element.scrollTop == (element.scrollHeight - element.offsetHeight) )
// Element scrolled to bottom
offsetHeight
должен давать фактическую видимую высоту элемента (включая отступы, поля и полосы прокрутки), а scrollHeight
- всю высоту элемента, включая невидимые (переполненные) области.
jQuery
.outerHeight()
должен давать аналогичный результат для JS .offsetHeight
- документация в MDN для offsetHeight
неясно о его кросс-браузерной поддержке. Чтобы охватить больше вариантов, это более полно:
var offsetHeight = ( container.offsetHeight ? container.offsetHeight : $(container).outerHeight() );
if ( container.scrollTop == (container.scrollHeight - offsetHeight) ) {
// scrolled to bottom
}
Ответ 19
Позвольте мне показать соответствие без JQuery. Простая функция JS:
function isVisible(elem) {
var coords = elem.getBoundingClientRect();
var topVisible = coords.top > 0 && coords.top < 0;
var bottomVisible = coords.bottom < shift && coords.bottom > 0;
return topVisible || bottomVisible;
}
Короткий пример того, как его использовать:
var img = document.getElementById("pic1");
if (isVisible(img)) { img.style.opacity = "1.00"; }
Ответ 20
Я использовал @ddonone answear и добавил вызов Ajax.
$('#mydiv').on('scroll', function(){
function infiniScroll(this);
});
function infiniScroll(mydiv){
console.log($(mydiv).scrollTop()+' + '+ $(mydiv).height()+' = '+ ($(mydiv).scrollTop() + $(mydiv).height()) +' _ '+ $(mydiv)[0].scrollHeight );
if($(mydiv).scrollTop() + $(mydiv).height() == $(mydiv)[0].scrollHeight){
console.log('bottom found');
if(!$.active){ //if there is no ajax call active ( last ajax call waiting for results ) do again my ajax call
myAjaxCall();
}
}
}
Ответ 21
Чтобы остановить повторное оповещение о ответе Ника.
ScrollActivate();
function ScrollActivate() {
$(window).on("scroll", function () {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).off("scroll");
alert("near bottom!");
}
});
}
Ответ 22
Google Chrome дает полную высоту страницы, если вы звоните $(window).height()
Вместо этого используйте window.innerHeight
, чтобы получить высоту вашего окна.
Необходимая проверка должна быть:
if($(window).scrollTop() + window.innerHeight > $(document).height() - 50) {
console.log("reached bottom!");
}
Ответ 23
Здесь мои два цента как принятый ответ не работали для меня.
var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;