jQuery를 사용하여 사용자가 div의 맨 아래로 스크롤 할 때 감지


219

내부에 다양한 양의 내용이있는 div 상자 (플럭스라고 함)가 있습니다. 이 divbox의 오버플로가 자동으로 설정되어 있습니다.

이제 내가하려는 것은이 DIV 상자의 맨 아래로 스크롤을 사용하여 더 많은 내용을 페이지에로드 할 때이 방법을 알고 있지만 내용을로드하는 방법을 모른다는 것입니다. 사용자가 div 태그의 맨 아래로 스크롤 한 시간을 감지합니까? 전체 페이지에 대해하고 싶다면 .scrollTop을 가져 와서 .height에서 빼십시오.

하지만 여기서는 그렇게 할 수 없습니까?

플럭스에서 .scrollTop을 가져 와서 inner라는 div에 모든 내용을 래핑하려고했지만 innerHeight of flux를 가져 가면 564px (div는 높이로 500으로 설정 됨)와 'innner'높이를 반환합니다. div의 맨 아래에 564가 표시되면 1064와 스크롤 탑을 반환합니다.

어떡해?

답변:


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 () 메소드는 문서에 이벤트 핸들러를 첨부하는 데 선호되는 메소드입니다.


2
DOM이 # flux-element가 이미 사용 가능한지 확인할 준비가되면 바인딩을 수행합니다.
Dr.Molle

1
당신은 당신이 대신 바인드의 ON 사용하여 응답, 바인드에 찬성되지 않습니다 업데이트해야합니다
ncubica

34
참고 : 사용자가 브라우저에서 확대 / 축소 수준을 사용하는 경우 작동하지 않을 수 있습니다. 확대 / 축소는 innerHeight()소수를보고합니다. 사용자가 축소하는 경우 scrollTop()및 의 합 innerHeight()은 항상 최소 분수 이상입니다 scrollHeight. 버퍼 영역을 20px로 추가했습니다. 그 결과 조건이었다 if(el.scrollTop() + el.innerHeight() >= el[0].scrollHeight - 20)el같습니다 $(this).
Nick

1
이것은 나에게 아주 잘 맞는 최고의 답변입니다. 감사합니다
Ashish Yadav

1
당신이 왜 작동하지 않습니다, 감사합니다 확인을 기쁘게 할 수 더 이상 작동하지 않습니다
UMAIR 샤 Yousafzai

50

창을 스크롤 할 때 아래쪽에서 표시된 div의 끝이 경고를 표시하는 해결책을 찾았습니다.

$(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 의 사이드 바 동작 에서와 같이 도와주세요 :)
Alyssa Reyes

그것은 마술처럼 작동하지만 경고가 두 번 실행된다는 문제가 있습니다. 내부에 함수를 호출하면 두 번 실행됩니다
Afaf

1
@ 1616 var running = false전에 변수를 선언했습니다. 조건부 안에서 확인합니다. if(!running) { running = true; // and continue logic } 이 방법은 한 번만 호출됩니다! AJAX가 완료되면 다음과 같이 설정하십시오.running = false;
Jacob Raccuia

1
그것은 창에 관한 것이지만 질문은 div에 관한 것입니다.
Alexander Volkov

42

이 질문은 5.5 년 전에 제기되었지만 오늘날의 UI / UX 컨텍스트와 관련이 있습니다. 그리고 2 센트를 추가하고 싶습니다.

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를 사용하지 않는 경우 찾고있는 솔루션입니다.
Petter Pettersson 2016 년

이벤트 핸들러가 있습니까?
Alexander Volkov

@AlexanderVolkov onscroll이 관련 이벤트입니다.
Thinking

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

overflow-y가 숨겨진 또는 스크롤로 표시된 div에서 이것을 사용해야하는 경우 이와 같은 것이 필요할 수 있습니다.

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

prop scrollHeight가 둥글거나 아마도 1 미만으로 꺼져있는 다른 이유 때문에 ceil이 필요하다는 것을 알았습니다.


3

Math.round () 함수를 사용하지 않는 경우 솔루션 하지 않으면 브라우저 창에 확대 / 축소가있는 경우 Dr.Molle에서 제안한 이 작동하지 않을 수 있습니다.

예를 들어 $ (this) .scrollTop () + $ (this) .innerHeight () = 600

$ (this) [0] .scrollHeight 수율 = 599.99998

600> = 599.99998이 실패합니다.

올바른 코드는 다음과 같습니다.

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되면 요소의 첫 번째 하위 요소를 선택하십시오.mob_top_menu[0].scrollHeight


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의 코드입니다.


-1

다른 버전이 있습니다.

키 코드는 overflow : scroll을 사용하여 스크롤 섹션을 포함하는 div의 높이로 입력을받는 function scroller ()입니다. 상단 또는 하단에서와 같이 상단에서 약 5px 또는 하단에서 10px입니다. 그렇지 않으면 너무 민감합니다. 10px가 최소값 인 것 같습니다. 하단 높이를 얻기 위해 div 높이에 10을 더한 것을 볼 수 있습니다. 5px가 작동한다고 가정하고 광범위하게 테스트하지 않았습니다. YMMV. scrollHeight는 표시된 div 높이가 아닌 내부 스크롤 영역의 높이를 반환합니다 (이 경우 400px).

<?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 PHP에서 javascript + css 코드를 생성하는 것은 나쁜 습관입니다 (유지하기가 어렵고 재사용이 불가능하며 웹 사이트 최적화가 없습니다). 또한 @Alexander Millar가 지적한 것처럼 패딩을 고려하여 10px 오프셋을 수정할 수 있습니다. 이 코드의 사용을 고려하는 사람은 두 번 생각해야합니다.
Kapitein Witbaard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.