Phát hiện khi người dùng cuộn xuống dưới cùng của div với jQuery


218

Tôi có một hộp div (được gọi là thông lượng) với một lượng nội dung khác nhau bên trong. Divbox này có tràn được đặt thành tự động.

Bây giờ, những gì tôi đang cố gắng làm là, khi sử dụng cuộn xuống dưới cùng của hộp DIV này, tải thêm nội dung vào trang, tôi biết cách thực hiện việc này (tải nội dung) nhưng tôi không biết làm thế nào để phát hiện khi người dùng đã cuộn xuống dưới cùng của thẻ div? Nếu tôi muốn làm điều đó cho toàn bộ trang, tôi sẽ lấy .scrollTop và trừ nó khỏi .height.

Nhưng tôi dường như không thể làm điều đó ở đây?

Tôi đã thử lấy .scrollTop từ thông lượng, và sau đó gói tất cả nội dung bên trong một div được gọi là bên trong, nhưng nếu tôi lấy phần bên trong của thông lượng, nó sẽ trả về 564px (div được đặt thành 500 là chiều cao) và chiều cao của 'innner' nó trả về 1064 và cuộn, khi ở dưới cùng của div nói 564.

Tôi có thể làm gì?

Câu trả lời:


420

Có một số thuộc tính / phương thức bạn có thể sử dụng:

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

Vì vậy, bạn có thể lấy tổng của hai thuộc tính đầu tiên và khi nó bằng với thuộc tính cuối cùng, bạn đã đạt đến cuối:

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

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

Chỉnh sửa: Tôi đã cập nhật 'liên kết' thành 'trên' theo:

Kể từ jQuery 1.7, phương thức .on () là phương thức ưa thích để đính kèm các trình xử lý sự kiện vào tài liệu.


2
Nó sẽ thực hiện liên kết khi DOM sẵn sàng để chắc chắn rằng phần tử # flux đã có sẵn.
Dr.Molle

1
bạn nên cập nhật câu trả lời của mình bằng cách sử dụng BẬT thay vì liên kết, liên kết không được chấp nhận để ủng hộ On
ncubica

34
Lưu ý: Khi người dùng đang sử dụng các mức thu phóng trên trình duyệt của họ, điều này có thể không hoạt động. Thu phóng nguyên nhân innerHeight()để báo cáo số thập phân. Trong trường hợp người dùng thu nhỏ, tổng scrollTop()innerHeight()sẽ luôn luôn thiếu ít nhất một phần scrollHeight. Tôi đã kết thúc việc thêm một vùng đệm 20px. Các điều kiện kết quả là if(el.scrollTop() + el.innerHeight() >= el[0].scrollHeight - 20)nơi elbằng $(this).
Nick

1
Đây là câu trả lời tốt nhất từng làm việc rất tốt cho tôi. Cảm ơn
Ashish Yadav

1
Nó không hoạt động nữa, bạn có thể vui lòng xác nhận rằng tại sao nó không hoạt động không, Cảm ơn
Umair Shah Yousafzai

50

Tôi tìm thấy một giải pháp mà khi bạn cuộn cửa sổ và kết thúc một div hiển thị từ dưới lên sẽ cho bạn một cảnh báo.

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

Trong ví dụ này nếu bạn cuộn xuống khi div ( .posts) kết thúc, nó sẽ cho bạn một cảnh báo.


cảm ơn bạn vì điều này nhưng làm thế nào tôi có thể làm cho div animate khi nó chạm đến đáy của div đó? Ngoài ra, khi bạn cuộn lên, hãy phát hiện đỉnh của div đó. Giống như ở đây trên trang web này lazada.com.ph/apple hành vi thanh bên Hy vọng bạn có thể giúp tôi :)
Alyssa Reyes

Nó hoạt động như một phép thuật nhưng vấn đề là cảnh báo được thực thi hai lần, vì vậy nếu bạn có lệnh gọi hàm bên trong thì nó sẽ được thực thi hai lần
Afaf

1
@ 1616 Tôi có một biến được var running = falsekhai báo trước đó. Trong điều kiện, tôi kiểm tra if(!running) { running = true; // and continue logic } Cách này chỉ được gọi một lần! Khi AJAX hoàn tất, hãy đặtrunning = false;
Jacob Raccuia

1
Đó là về cửa sổ, nhưng câu hỏi là về div.
Alexander Volkov

42

Mặc dù câu hỏi đã được hỏi cách đây 5,5 năm, nhưng nó vẫn liên quan nhiều hơn đến bối cảnh UI / UX ngày nay. Và tôi muốn thêm hai xu của tôi.

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

Nguồn: https://developer.mozilla.org/en-US/docs/Web/API/Euity/scrollHeight#Determine_if_an_element_has_been_totally_scrolled

Một số phần tử sẽ không cho phép bạn cuộn toàn bộ chiều cao của phần tử. Trong những trường hợp bạn có thể sử dụng:

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

2
Đây là giải pháp bạn đang tìm kiếm nếu bạn không sử dụng jQuery.
Petter Pettersson

Có xử lý sự kiện?
Alexander Volkov

@AlexanderVolkov onscroll là sự kiện liên quan.
Suy nghĩ

9

Chỉ cần một ghi chú bổ sung ở đây là tôi đã tìm thấy điều này khi tìm kiếm một giải pháp cho một div cố định mà tôi muốn cuộn. Đối với kịch bản của tôi, tôi thấy rằng nên tính đến phần đệm trên div để có thể đánh chính xác. Vì vậy, mở rộng câu trả lời của @ Dr.Molle tôi thêm vào như sau

$('#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');
    }
  });

Điều đó sẽ cung cấp cho bạn vị trí chính xác, bao gồm phần đệm và đường viền


7

điều này làm việc cho tôi mặc dù

$(window).scroll(function() {
  if ($(window).scrollTop() >= (($(document).height() - $(window).height()) - $('#divID').innerHeight())) {
    console.log('div reached');
  }
});

3

Nếu bạn cần sử dụng điều này trên một div có tràn hoặc y như ẩn hoặc cuộn, một cái gì đó như thế này có thể là những gì bạn cần.

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

Tôi thấy trần nhà là cần thiết bởi vì cuộn propHeight dường như tròn, hoặc có lẽ một số lý do khác khiến điều này bị tắt ít hơn 1.


3

Nếu bạn không sử dụng hàm Math.round (), giải pháp được đề xuất bởi Dr.Molle sẽ không hoạt động trong một số trường hợp khi cửa sổ trình duyệt có thu phóng.

Ví dụ: $ (này) .scrollTop () + $ (này) .innerHeight () = 600

$ (này) [0] .scrollHeight mang lại = 599.99998

600> = 599.99998 không thành công.

Đây là mã chính xác:

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

Bạn cũng có thể thêm một số pixel lề phụ nếu bạn không cần một điều kiện nghiêm ngặt

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

Trong việc sử dụng DOM đơn giản, bạn có thể kiểm tra điều kiện

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

nếu đúng thì bạn đã đạt đến đích.


1

Nếu người nào bị scrollHeightnhư undefined, sau đó chọn subelement 1 yếu tố:mob_top_menu[0].scrollHeight


1

không chắc nó có giúp được gì không nhưng đây là cách tôi làm.

Tôi có một bảng chỉ mục lớn hơn cửa sổ và tôi để nó cuộn cho đến khi kết thúc chỉ số này. Sau đó, tôi sửa nó ở vị trí. Quá trình được đảo ngược khi bạn cuộn về phía trên cùng của trang.

Trân trọng.

<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

Mặc dù điều này đã được hỏi gần 6 năm, nhưng trước đây vẫn là chủ đề nóng trong thiết kế UX, đây là đoạn giới thiệu nếu bất kỳ người mới nào muốn sử dụng

$(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

Các bạn, đây là giải pháp cho vấn đề thu phóng, nó hoạt động với tất cả các mức thu phóng, trong trường hợp bạn cần:

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
    }
});

Đây là mã trên github.


-1

Đây là một phiên bản khác.

Mã khóa là chức năng cuộn () lấy đầu vào làm chiều cao của div chứa phần cuộn, sử dụng overflow: scroll. Nó xấp xỉ 5px từ trên cùng hoặc 10px từ dưới cùng như ở trên cùng hoặc dưới cùng. Nếu không thì nó quá nhạy cảm. Có vẻ như 10px là về mức tối thiểu. Bạn sẽ thấy nó thêm 10 vào chiều cao div để có được chiều cao dưới cùng. Tôi cho rằng 5px có thể hoạt động, tôi đã không thử nghiệm rộng rãi. YMMV. scrollHeight trả về chiều cao của vùng cuộn bên trong, không phải chiều cao được hiển thị của div, trong trường hợp này là 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 vì việc tạo mã javascript + css từ php là một cách làm không tốt (khó bảo trì, không thể sử dụng lại, không tối ưu hóa trang web, v.v.). Hơn nữa, như được chỉ ra bởi @Alexander Millar, độ lệch 10px có thể được sửa bằng cách lấy phần đệm vào tài khoản. Bất cứ ai xem xét việc sử dụng mã này nên suy nghĩ hai lần ...
Kapitein Witbaard
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.