การตรวจจับเมื่อผู้ใช้เลื่อนไปด้านล่างของ div ด้วย jQuery


219

ฉันมีกล่อง div (เรียกว่าฟลักซ์) ที่มีเนื้อหาในตัวแปรจำนวนหนึ่ง divbox นี้ตั้งค่าโอเวอร์โฟลว์เป็นอัตโนมัติ

ตอนนี้สิ่งที่ฉันพยายามทำคือเมื่อใช้เลื่อนไปที่ด้านล่างของกล่อง DIV นี้โหลดเนื้อหาเพิ่มเติมลงในหน้าฉันรู้วิธีการทำ (โหลดเนื้อหา) แต่ฉันไม่ทราบวิธีการ ตรวจพบเมื่อผู้ใช้เลื่อนไปที่ด้านล่างของแท็ก div หรือไม่ ถ้าฉันต้องการทำทั้งหน้าฉันจะใช้. scopTop แล้วลบมันออกจาก. high

แต่ฉันไม่สามารถทำได้ที่นี่ใช่ไหม

ฉันได้ลองใช้. scrollTop จากฟลักซ์แล้วห่อเนื้อหาทั้งหมดใน div ที่เรียกว่า Inner แต่ถ้าฉันใช้ InnerHeight of flux มันจะคืนค่า 564px (div ถูกตั้งไว้ที่ 500 เป็นความสูง) และความสูงของ 'innner' มันจะคืนค่า 1,064 และ scrolltop เมื่อที่ด้านล่างของ div บอกว่า 564

ฉันควรทำอย่างไร

คำตอบ:


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 แทนการโยงการผูกจะเลิกใช้เมื่อวันที่ 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 Shah 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 ของวันนี้ และฉันต้องการเพิ่มสองเซ็นต์ของฉัน

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

มีตัวจัดการเหตุการณ์หรือไม่
Alexander Volkov

@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 เป็น hidden หรือ scroll สิ่งที่คล้ายกันนี้อาจเป็นสิ่งที่คุณต้องการ

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

ฉันพบเพดานจำเป็นเพราะ prop scrollHeight ดูเหมือนจะปัดเศษหรืออาจมีสาเหตุอื่นที่ทำให้สิ่งนี้ปิดน้อยกว่า 1


3

หากคุณไม่ได้ใช้ฟังก์ชัน Math.round () การแก้ปัญหาที่แนะนำโดย Dr.Molle จะไม่ทำงานในบางกรณีเมื่อหน้าต่างเบราว์เซอร์มีการซูม

ตัวอย่างเช่น $ (this) .scrollTop () + $ (this) .innerHeight () = 600

$ (นี่) [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นั้นให้เลือกองค์ประกอบย่อยที่ 1 ขององค์ประกอบ: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

นี่คือรุ่นอื่น

รหัสสำคัญคือฟังก์ชั่น scroller () ซึ่งรับอินพุตเป็นความสูงของ div ที่มีส่วนการเลื่อนโดยใช้ overflow: scroll มันประมาณ 5px จากด้านบนหรือ 10px จากด้านล่างเช่นที่ด้านบนหรือด้านล่าง ไม่งั้นมันไวเกินไป ดูเหมือนว่า 10px นั้นเกี่ยวกับขั้นต่ำ คุณจะเห็นมันเพิ่ม 10 ถึงความสูง div เพื่อให้ได้ความสูงด้านล่าง ฉันถือว่า 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 เนื่องจากการสร้าง javascript + css code จาก php เป็นการปฏิบัติที่ไม่ดี (ยากที่จะรักษาไม่มีการใช้ซ้ำไม่มีการเพิ่มประสิทธิภาพเว็บไซต์ ฯลฯ ) นอกจากนี้ตามที่ระบุโดย @Alexander Millar การชดเชย 10px สามารถแก้ไขได้โดยการเติมเข้าไปในบัญชี ทุกคนที่พิจารณาใช้รหัสนี้ควรคิดสองครั้ง ...
Kapitein Witbaard
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.