ตรวจสอบว่าผู้ใช้เลื่อนไปด้านล่างหรือไม่


668

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

ปัญหาเดียวคือฉันไม่รู้วิธีตรวจสอบว่าผู้ใช้เลื่อนไปที่ด้านล่างของหน้าด้วย jQuery ความคิดใด ๆ

ฉันต้องการค้นหาวิธีการตรวจสอบเมื่อผู้ใช้เลื่อนไปที่ด้านล่างของหน้าด้วย jQuery


มันตลกดีฉันพยายามคิดว่าฟังก์ชั่นใดถูกเรียกใช้เมื่อฉันเลื่อนไปที่ด้านล่างดังนั้นฉันจึงสามารถปิดกั้น "คุณสมบัติ" ที่น่ารำคาญนี้ได้
endolith

สำหรับโซลูชัน React.js ลิงก์นี้อาจช่วยได้: stackoverflow.com/a/53158893/4265546
raksheetbhat

คำตอบ:


1024

ใช้.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ให้เป็นพิกเซลอะไรก็ได้จากด้านล่างที่คุณต้องการเปิดใช้งาน


32
ตามปกติคุณไปถึงที่นั่นก่อนฉัน อย่างไรก็ตามสำหรับ OP หากคุณมีคอนเทนเนอร์ของบทความให้ใช้ ID แทน "หน้าต่าง" นอกจากนี้คุณอาจต้องการเปลี่ยน. height () ล่าสุดเป็น scrollHeight
Christian

4
Firefox เรียกการแจ้งเตือน ("ด้านล่าง!"); หลายครั้ง (ทำงานได้ดีกับโครเมี่ยมและซาฟารี)
Marco Matarazzi

3
มันค่อนข้างบั๊กถ้าคุณทำconsole.log()แทนการเตือนบางครั้งคำสั่งซ้ำ
Jürgen Paul

19
การรวมกัน @KevinVella Vella ที่ดีคือการใช้สิ่งนี้กับ _.debounce () ในยูทิลิตี้ขีดล่างเพื่อป้องกันการยิงจนกว่าผู้ใช้จะหยุดการเลื่อน - underscorejs.org/#debounce -
JohnnyFaldo

3
@NickCraver มีการใช้งาน js จริงหรือไม่
Dewsworld

116

คำตอบของ 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!");
       }
   });

6
เขาได้อัปเดตด้วยฟังก์ชันเวอร์ชันที่บีบอัดเล็กน้อย 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); }
ดึง

ที่แจ้งเตือนฉันเมื่อฉันไปถึงด้านบนไม่ใช่ด้านล่าง (Chrome)
ดาเมียนโรช

อาจเป็นการดีกว่าที่จะใช้minแทนmaxโดยเฉพาะอย่างยิ่งหากมีขอบเพิ่มเติมเพื่อหลีกเลี่ยงการป้องกันไม่ให้ผู้ใช้เลื่อนไปยังสิ่งที่คุณคิดว่าเป็นด้านล่างของหน้า
โซโลมอน Ucko

104

ฉันไม่แน่ใจว่าทำไมถึงยังไม่ได้โพสต์ แต่ตามเอกสารจาก MDNวิธีที่ง่ายที่สุดคือการใช้คุณสมบัติจาวาสคริปต์:

element.scrollHeight - element.scrollTop === element.clientHeight

ผลตอบแทนจริงเมื่อคุณอยู่ที่ด้านล่างขององค์ประกอบใด ๆ ที่เลื่อนได้ ดังนั้นเพียงแค่ใช้ 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. สิ่งนี้ควรจะปลอดภัยในเบราว์เซอร์


1
โปรดทราบว่าในบางสถานการณ์อาจไม่เป็นเช่นนั้น Firefox 47 รายงานว่าลูกค้า textareaHight เป็น 239 ในขณะที่สมการข้างต้นให้ 253 เมื่อเลื่อนไปที่ด้านล่าง อาจมีช่องว่างภายใน / ขอบหรือสิ่งที่มีผลต่อมัน? ไม่ว่าจะด้วยวิธีใดการเพิ่มห้องเลื้อยก็ไม่เจ็บเหมือนvar isAtBottom = ( logField.scrollHeight - logField.scrollTop <= logField.clientHeight + 50 );กัน สิ่งนี้มีประโยชน์สำหรับการเลื่อนฟิลด์โดยอัตโนมัติเฉพาะเมื่ออยู่ที่ด้านล่างแล้ว (เพื่อให้ผู้ใช้สามารถตรวจสอบส่วนเฉพาะของบันทึกเรียลไทม์โดยไม่ต้องเสียตำแหน่ง ฯลฯ )
Beejor

ฉันจะเพิ่มว่ามันเป็นไปได้ที่มันจะคืนค่าลบเท็จเนื่องจากด้านหนึ่งสามารถคืนค่าทศนิยมเล็กน้อยได้ในขณะที่อีกด้านหนึ่งคืนค่าจำนวนเต็มทั้งหมด (เช่น200.181819304947และ200) ฉันได้เพิ่มเข้าไปMath.floor()เพื่อช่วยจัดการกับสิ่งนั้น แต่ฉันไม่รู้ว่าจะเชื่อถือได้แค่ไหน
ฮันนา

1
สำหรับฉันมันไม่ทำงานข้ามเบราว์เซอร์ ฉันได้รับผลลัพธ์ที่แตกต่างอย่างสิ้นเชิงกับโครเมี่ยมเมื่อเทียบกับ Firefox
Tadej

1
ฉันลองสิ่งนี้ในองค์ประกอบ <body> และนี่เป็นการเริ่มขึ้นเมื่อเบราว์เซอร์เลื่อนไปที่ด้านบนไม่ใช่ด้านล่าง
Chris Sobolewski

10
Math.abs(element.scrollHeight - element.scrollTop - element.clientHeight) <= 3.0(แทนที่ 3.0 ด้วยความอดทนต่อพิกเซลที่คุณคิดว่าเหมาะสมกับสถานการณ์ของคุณ) นี่คือวิธีที่จะไปเพราะ (A) clientHeight, scrollTopและclientHeightทั้งหมดที่โค้งมนซึ่งอาจนำไปสู่ข้อผิดพลาด 3PX ถ้าจัดทั้งหมด (B) 3 แสนพิกเซลคือแทบจะไม่สามารถมองเห็นให้กับผู้ใช้เพื่อให้ผู้ใช้อาจคิดว่ามีสิ่งผิดปกติกับเว็บไซต์ของคุณ เมื่อพวกเขา "คิด" พวกเขาจะอยู่ที่ด้านล่างของหน้าเมื่อพวกเขาไม่ได้และ (C) อุปกรณ์บางอย่าง (โดยเฉพาะอย่างยิ่งที่ไม่มีเมาส์) สามารถมีพฤติกรรมแปลก ๆ เมื่อเลื่อน
Jack Giffin

50

สำหรับผู้ที่ใช้โซลูชันของ Nick และรับการแจ้งเตือน / การยิงซ้ำเหตุการณ์คุณสามารถเพิ่มบรรทัดของรหัสเหนือตัวอย่างการแจ้งเตือน:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       $(window).unbind('scroll');
       alert("near bottom!");
   }
});

ซึ่งหมายความว่ารหัสจะเริ่มทำงานในครั้งแรกที่คุณมีขนาดไม่เกิน 100px ของด้านล่างของเอกสาร มันจะไม่ทำซ้ำหากคุณเลื่อนกลับขึ้นและจากนั้นกลับลงมาซึ่งอาจมีหรือไม่มีประโยชน์ขึ้นอยู่กับสิ่งที่คุณใช้รหัสของ Nick


1
ฉันเพิ่งจะแสดงความคิดเห็นและบอกว่าบรรทัดของโค้ดนั้นเกี่ยวข้องกับคำตอบของคนอื่น แต่ +1 สำหรับเจตนา!
Nate-Wilkins

ขออภัยฉันไม่สามารถ (และยังไม่สามารถ) ดูวิธีเพิ่มความคิดเห็นในคำตอบ (เช่นเดียวกับที่นี่)
Tim Carr

ใช่ผู้ใช้ใหม่ไม่สามารถเพิ่มความคิดเห็นในโพสต์เว้นแต่คุณจะได้รับตัวแทนเพิ่มเติม
Nate-Wilkins

ด้านแรกถ้าคุณสามารถใส่ที่แตกต่างกันหากการทดสอบว่าการเปลี่ยนแปลงที่คุณต้องการให้สคริปต์ที่มีอยู่ให้พูดชั้นเรียนที่มีการใช้กับ div สิ่งนี้จะทำให้ซ้อนกันที่สองหากไม่ได้ทำงานถ้ามันได้ทำงานแล้ว
1934286

ฉันจะเลือกรหัส div เฉพาะแทนทั้งหน้าต่างได้อย่างไร
James Smith

40

นอกเหนือจากคำตอบที่ได้รับการยอมรับอย่างดีเยี่ยมจาก 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);
}

มันอาจจะควรจะชี้ให้เห็นว่าเรื่องนี้ต้อง Underscore.js: underscorejs.org มันเป็นจุดที่ดีมาก เหตุการณ์การเลื่อนควรจะถูกควบคุมปริมาณมากเสมอเพื่อหลีกเลี่ยงปัญหาประสิทธิภาพการทำงานที่ร้ายแรง
Jude Osborn

อาจเป็นเพียงฉันและสามารถใช้การเปรียบเทียบได้ แต่ฉันไม่ชอบแนวคิดของการเรียกใช้ clearTimeout และ setTimeout ในทุกเหตุการณ์การเลื่อน ฉันจะออก 1 setTimeout และเพิ่มยามใน handler นั้น มันอาจเป็นเพียงการเพิ่มประสิทธิภาพขนาดเล็ก (ถ้าทั้งหมด)
หน้าตาบูดบึ้งของ Despair

นี่เป็นส่วนเสริมที่เรียบร้อยจริงๆ! ฉันสามารถนึกถึงการปรับปรุงเพิ่มเติมอย่างใดอย่างหนึ่ง ปัจจุบันฟังก์ชั่นที่ตรวจสอบความสูงจะไม่ทำงานหากผู้ใช้ยังคงเลื่อน หากเป็นปัญหา (เช่นคุณต้องการเปิดใช้งานฟังก์ชั่นเมื่อผู้ใช้เลื่อนลงครึ่งหนึ่งโดยไม่คำนึงถึงว่าพวกเขายังคงเลื่อน) คุณสามารถตรวจสอบให้แน่ใจว่าฟังก์ชั่นได้รับการเรียกจริงในขณะที่ยังคงห้ามโทรหลายสาย นี่คือส่วนสำคัญที่จะแสดงมัน gist.github.com/datacarl/7029558
datacarl

อะไร? เรียกใช้การโหลดของเครื่องจักรเพื่อป้องกันการคำนวณอย่างง่ายหรือไม่? ฉันไม่เห็นว่ามันจะมีประสิทธิภาพมากขึ้นได้อย่างไร
Rambatino

37

คำตอบของ Nick Craver ต้องได้รับการแก้ไขเล็กน้อยเพื่อให้ทำงานบน iOS 6 Safari Mobile และควรเป็น:

$(window).scroll(function() {
   if($(window).scrollTop() + window.innerHeight == $(document).height()) {
       alert("bottom!");
   }
});

เปลี่ยน$ (หน้าต่าง) .height ()เพื่อwindow.innerHeightควรจะทำเพราะเมื่อแถบที่อยู่ที่ถูกซ่อนอยู่ 60px จะมีการเพิ่มความสูงของหน้าต่าง แต่ใช้$(window).height()ไม่ได้สะท้อนให้เห็นถึงการเปลี่ยนแปลงนี้ในขณะที่ใช้window.innerHeightไม่

หมายเหตุ : window.innerHeightคุณสมบัตินี้ยังรวมถึงความสูงของแถบเลื่อนแนวนอน (หากมีการแสดงผล) $(window).height()ซึ่งแตกต่างจากที่จะไม่รวมความสูงของแถบเลื่อนแนวนอน นี่ไม่ใช่ปัญหาใน Mobile Safari แต่อาจก่อให้เกิดพฤติกรรมที่ไม่คาดคิดในเบราว์เซอร์อื่นหรือ Mobile Safari รุ่นต่อไป การเปลี่ยน==เป็น>=สามารถแก้ไขปัญหานี้สำหรับกรณีการใช้งานทั่วไป

อ่านเพิ่มเติมเกี่ยวกับwindow.innerHeightอสังหาริมทรัพย์ที่นี่


window.innerHeight ทำให้รู้สึกถึงสิ่งที่ฉันพยายามที่จะสำเร็จขอบคุณมาก!
Amir5000

วิธีรับความสูงที่เหลือหลังจากการเลื่อน
OPV

20

นี่เป็นวิธีการที่ค่อนข้างง่าย

const didScrollToBottom = elm.scrollTop + elm.clientHeight == elm.scrollHeight

ตัวอย่าง

elm.onscroll = function() {
    if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) {
        // User has scrolled to the bottom of the element
    }
}

ในกรณีที่เป็นองค์ประกอบที่ดึงมาจากคือelmdocument.getElementById


17

นี่คือส่วนหนึ่งของรหัสที่จะช่วยให้คุณแก้จุดบกพร่องรหัสของฉันฉันทดสอบคำตอบข้างต้นและพบว่าพวกเขาจะเป็นรถบั๊ก ฉันได้ทดสอบสิ่งต่อไปนี้บน 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>

อาจมีวิธีแก้ปัญหาที่ง่ายกว่านี้ แต่ฉันหยุดที่จุดที่มันทำงาน

หากคุณยังคงมีปัญหากับเบราว์เซอร์ปลอมบางตัวนี่คือรหัสบางส่วนที่จะช่วยคุณในการแก้ไขปัญหา:

<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;">

ฉันหวังว่านี้จะช่วยให้ใครบางคนในเวลา


คำตอบที่ดีที่สุดสำหรับ Vanilla js, ไม่มีวิธีแก้ปัญหา jQuery ใช้var docElement = document.documentElement; var winElement = window
jperelli

นี้ใน 2019 แทนที่จะคุณยังสามารถใช้winElement.pageYOffset winElement.scrollY
Noel Abrahams

15

โปรดตรวจสอบคำตอบนี้

 window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
       console.log("bottom");
    }
};

คุณสามารถทำfooterHeight - document.body.offsetHeightเพื่อดูว่าคุณอยู่ใกล้ส่วนท้ายหรือถึงส่วนท้ายหรือไม่


12
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

มันจะคำนวณแถบเลื่อนระยะทางไปที่ด้านล่างขององค์ประกอบ เท่ากับ 0 ถ้าแถบเลื่อนถึงด้านล่าง


1
ฉันทำสิ่งต่อไปนี้และทำงานได้อย่างไร้ที่ติ ขอบคุณ var shouldScroll = (elem.scrollHeight - elem.scrollTop - elem.clientHeight) == 0;
jiminssy

11

นี่คือสองเซ็นต์ของฉัน:

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

พยายามใช้วิธีแก้ปัญหาของคุณมันใช้งานได้ดี แต่ในกรณีที่องค์ประกอบมีช่องว่างภายใน - มันไม่ทำงานเพราะมันคำนวณความสูงขององค์ประกอบโดยไม่รวมถึงช่องว่างภายในเพื่อแก้ไขปัญหานี้ฉันเปลี่ยนสิ่งนี้$(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight=>$(this).scrollTop() + $(this).outerHeight(true) >= $(this)[0].scrollHeight
Taras Chernata

6

Pure JSพร้อมcross-browserและ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ไม่ได้เขียนโดยฉัน

ฉันแค่แสดงให้เห็นว่ามันทำงานอย่างไรและฉันจะทำยังไง


สมบูรณ์ ทดสอบใน Firefox และ Chrome
Erlisar Vasquez

ฉันได้รับข้อผิดพลาดต่อไปนี้: คาดว่าจะมีข้อโต้แย้ง 3 ข้อ แต่ได้รับ 2 ข้อโต้แย้ง 'c' ไม่ได้ระบุไว้
Sober

6

โซลูชันของฉันใน 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>


4

ลองใช้เงื่อนไขการจับคู่หากเลื่อนไปสุดล่าง

if ($(this)[0].scrollHeight - $(this).scrollTop() == 
    $(this).outerHeight()) {

    //code for your custom logic

}

3

Nick ตอบคำถามได้ดี แต่คุณจะมีฟังก์ชั่นที่ซ้ำตัวเองในขณะที่เลื่อนหรือจะไม่ทำงานเลยหากผู้ใช้มีการซูมหน้าต่าง ฉันมาพร้อมกับการแก้ไขง่ายๆแค่ math.round ความสูงแรกและใช้งานได้ตามที่คาดไว้

    if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){
    loadPagination();
    $(".go-up").css("display","block").show("slow");
}


2

สิ่งนี้ให้ผลลัพธ์ที่แม่นยำเมื่อตรวจสอบองค์ประกอบที่เลื่อนได้(เช่นไม่ใช่window):

// `element` is a native JS HTMLElement
if ( element.scrollTop == (element.scrollHeight - element.offsetHeight) )
    // Element scrolled to bottom

offsetHeightควรให้ความสูงที่มองเห็นได้จริงขององค์ประกอบ (รวมถึงการเว้นระยะขอบและแถบเลื่อน) และscrollHeightเป็นความสูงทั้งหมดขององค์ประกอบรวมถึงพื้นที่ที่มองไม่เห็น (ล้น)

jQuery's .outerHeight()ควรให้ผลคล้ายกับ JS ของ.offsetHeight- เอกสารใน MDN สำหรับoffsetHeightเป็นที่ชัดเจนเกี่ยวกับการสนับสนุนเบราว์เซอร์ของมัน เพื่อให้ครอบคลุมตัวเลือกเพิ่มเติมสิ่งนี้สมบูรณ์ยิ่งขึ้น:

var offsetHeight = ( container.offsetHeight ? container.offsetHeight : $(container).outerHeight() );
if  ( container.scrollTop == (container.scrollHeight - offsetHeight) ) {
   // scrolled to bottom
}

ลองMath.floor(element.scrollTop) === element.scrollHeight - element.offsetHeightในกรณีที่เป็นทศนิยม scrollTop มันจะไม่ทำงานโดยไม่ต้องมีMath.floor()
Michail Michailidis

1

โซลูชันทั้งหมดนี้ใช้ไม่ได้กับฉันใน Firefox และ Chrome ดังนั้นฉันจึงใช้ฟังก์ชั่นที่กำหนดเองจากMiles O'Keefeและmedural 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!");
    }
});

1

นี่คือสองเซ็นต์ของฉันเป็นคำตอบที่ยอมรับไม่ได้สำหรับฉัน

var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;

1

แทนที่จะฟังเหตุการณ์การเลื่อนการใช้Intersection Observerเป็นสิ่งที่ไม่แพงสำหรับการตรวจสอบว่าองค์ประกอบสุดท้ายนั้นปรากฏบนวิวพอร์ต (นั่นหมายความว่าผู้ใช้เลื่อนไปที่ด้านล่าง) นอกจากนี้ยังได้รับการสนับสนุนสำหรับ IE7 กับpolyfill

var observer = new IntersectionObserver(function(entries){
   if(entries[0].isIntersecting === true)
      console.log("Scrolled to the bottom");
   else
      console.log("Not on the bottom");
}, {
   root:document.querySelector('#scrollContainer'),
   threshold:1 // Trigger only when whole element was visible
});

observer.observe(document.querySelector('#scrollContainer').lastElementChild);
#scrollContainer{
  height: 100px;
  overflow: hidden scroll;
}
<div id="scrollContainer">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
  <div>Item 5</div>
  <div>Item 6</div>
  <div>Item 7</div>
  <div>Item 8</div>
  <div>Item 9</div>
  <div>Item 10</div>
</div>


ปัญหาของ Intersection Observer คือถ้าหน้าต่างเริ่มต้นมีขนาดค่อนข้างเล็ก (พูดเลย์เอาต์พื้นฐานก่อนดึงภาพโดยไม่มีแถบเลื่อน) ผู้โทรกลับผู้สังเกตการณ์จะถูกเรียกใช้ทันที ผู้ฟังเลื่อนรอให้บุคคลเลื่อน และแถบเลื่อนจะไม่ปรากฏขึ้นก่อนที่จะดึงรูปภาพชุดแรกและอื่น ๆ ดังนั้น Intersection Observer ไม่ได้อยู่ในโซลูชั่นเดียว
Aleks

@Aleks คุณสามารถโทรหา.observe(...)ผู้ฟังเหตุการณ์เช่นเมื่อผู้ใช้วางตัว / แตะภาชนะเลื่อนของคุณเพื่อที่จะไม่เรียกทันที
StefansArya

0

ฉันขอแสดงความนับถือที่ไม่มี 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";  }

5
สิ่งนี้ไม่ตอบคำถาม คำถามคือวิธีการตรวจสอบว่าผู้ใช้เลื่อนหน้าต่างไปจนถึงด้านล่าง รหัสของคุณกำลังตรวจสอบว่ามีองค์ประกอบใดที่อยู่ในมุมมอง
Peter Hall

0

ฉันใช้ @ddanone ตอบรับและเพิ่มการโทร 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();
    }
}

}


0

หากต้องการหยุดการเตือนซ้ำ ๆ สำหรับคำตอบของนิค

ScrollActivate();

function ScrollActivate() {
    $(window).on("scroll", function () {
        if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
            $(window).off("scroll");
            alert("near bottom!");
        }
    });
}

0

Google Chrome ให้ความสูงเต็มของหน้าถ้าคุณโทร $(window).height()

ใช้window.innerHeightเพื่อดึงความสูงของหน้าต่างแทน การตรวจสอบที่จำเป็นควรเป็น:

if($(window).scrollTop() + window.innerHeight > $(document).height() - 50) {
    console.log("reached bottom!");
}

0

เห็นได้ชัดว่าสิ่งที่ได้ผลสำหรับฉันคือ 'ร่างกาย' และไม่ใช่ 'หน้าต่าง' เช่นนี้:

$('body').scroll(function() {


 if($('body').scrollTop() + $('body').height() == $(document).height()) {
     //alert at buttom
 }
 });

สำหรับการใช้งานร่วมกันข้ามเบราว์เซอร์:

  function getheight(){
    var doc = document;
    return  Math.max(
        doc.body.scrollHeight, doc.documentElement.scrollHeight,
        doc.body.offsetHeight, doc.documentElement.offsetHeight,
        doc.body.clientHeight, doc.documentElement.clientHeight

        );
   }

จากนั้นแทน $ (เอกสาร) .height () เรียกใช้ฟังก์ชัน getheight ()

$('body').scroll(function() {


   if($('body').scrollTop() + $('body').height() == getheight()  ) {
     //alert at bottom
 }
});

สำหรับการใช้งานใกล้ด้านล่าง:

$('body').scroll(function() {


if($('body').scrollTop() + $('body').height() > getheight() -100 ) {
    //alert near bottom
 }
 });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.