web-dev-qa-db-ja.com

ユーザーが一番下までスクロールしたかどうかを確認

ユーザーが下にスクロールするとコンテンツがロードされるページ分割システム(Facebookのようなもの)を作っています。そのための最善の方法は、ユーザーがページの一番下にいるときを見つけて、より多くの投稿を読み込むためにajaxクエリを実行することです。

唯一の問題は、ユーザーがjQueryを使ってページの一番下までスクロールしたかどうかを確認する方法がわからないことです。何か案は?

ユーザーがjQueryでページの一番下までスクロールしたことを確認する方法を見つける必要があります。

601
Johnny

以下のように、window.scroll() イベントを使用します。

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

ここでテストすることができます これはウィンドウの一番上のスクロールを取得するので、どれくらい下にスクロールして表示ウィンドウの高さを追加し、それがコンテンツ全体の高さと等しいかどうかをチェックします(document)。代わりに、ユーザーが near 下部にいるかどうかを確認したい場合は、次のようになります。

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

ここでそのバージョンをテストすることができます 、その100を下からトリガーしたいピクセルに調整してください。

936
Nick Craver

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!");
       }
   });
110
Miles O'Keefe

なぜこれがまだ投稿されていないのかはっきりとはわかりませんが、 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はより正確です。clientHeightscrollTopは両方とも誰でもサポートされています。例6でも。これはクロスブラウザセーフであるべきです。

79

Nickのソリューションを使用していてアラート/イベントが繰り返し発生している場合は、アラートの例の上に次のコード行を追加できます。

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

これは、コードがドキュメントの下部から100px以内にあるときに初めて起動されることを意味します。上にスクロールしてから下にスクロールしても繰り返しません。Nicのコードを使用している目的によっては、これが役に立つ場合もあれば、役に立たない場合もあります。

47
Tim Carr

Nick Craverによる優れた回答に加えて、scrollイベントを頻繁に発生させないように調整することもできます。したがって、 ブラウザのパフォーマンスが向上します

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

Nick Craverの答えは、iOS 6 Safari Mobileで動作するように少し修正する必要があります。

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

$(window).height()window.innerHeightに変更すると、アドレスバーが非表示になったときにさらに60pxが追加されるためです。 window.innerHeightを使用している間、ウィンドウの高さが$(window).height()を使用しても、この変更はではありません

Note:水平スクロールバーの高さを含まない$(window).height()とは異なり、window.innerHeightプロパティには水平スクロールバーの高さ(レンダリングされている場合)も含まれます。これはMobile Safariの問題ではありませんが、他のブラウザまたは将来のバージョンのMobile Safariでは予期しない動作を引き起こす可能性があります。 ==>=に変更すると、ほとんどの一般的な使用例でこれを修正できます。

window.innerHeightプロパティについてもっと読む ここ

36
Yosi

これはかなり単純なアプローチです。

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

これはあなたがあなたのコードをデバッグする手助けとなるコードの一部です、私は上記の答えをテストして、それらがバグがあるとわかりました。私は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がうまくいった時点でやめました

それでも不正なブラウザで問題が解決しない場合は、デバッグに役立つコードを次に示します。

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

私はこれが誰かの時間を節約することを願っています。

15
Talon
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

要素の下までの距離スクロールバーを計算します。スクロールバーが一番下に達した場合は0になります。

10
Vasyl Gutnyk

確認してください この答え

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

footerHeight - document.body.offsetHeightを実行して、自分がフッターの近くにいるのか、フッターに達するのかを確認できます

10
Junaid Qadir

これは私の2セントです:

$('#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
ddanone

純粋なJS with クロスブラウザ および デバウンス (かなり良い パフォーマンス

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:私によって書かれていないDebouncergetScrollXYgetDocHeight

私はちょうどその動作を示しています、そして私はどのようにします

5
l2aelba

次のコードを試すことができます、

$("#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');
    }
});
3
Shahrukh Anwar

一番下までスクロールしたら、これをマッチ条件として試してください

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

    //code for your custom logic

}
3
Hiren Patel

Nickはその罰金に答えますが、あなたはスクロールしている間それ自身を繰り返す機能を持っているか、またはユーザーがウィンドウをズームしているとまったく機能しないでしょう。私は最初の高さのまわりでちょうどちょうど数学。簡単な修正を思いついた、そしてそれは想定されるように働く。

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

スクロール可能な element をチェックすると(つまりwindowではない)、これは正確な結果を与えます。

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

offsetHeightは要素の 実際の表示 高さ(パディング、マージン、 - scrollbarsを含む)を指定し、scrollHeightは非表示(オーバーフロー)領域を含む要素の 全体 高さを示します。

jQuery.outerHeight()はJSの.offsetHeightと同様の結果を与えるはずです - offsetHeightに関するMDNのドキュメントはクロスブラウザサポートについては不明です。より多くのオプションをカバーするために、これはより完全です:

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

1
Yuval A.

これらすべての解決策はFirefoxとChrome上ではうまくいきませんので、 Miles O'Keefemeder 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
hayj

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

Nickの答えに対する繰り返しの警告を止める

ScrollActivate();

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

Google Chromeは、$(window).height()を呼び出すと、ページの全高を表示します

代わりに、window.innerHeightを使用して、ウィンドウの高さを取得します。必要なチェックは次のとおりです。

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

@ddanone 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();
    }
}

}

0
Henrique C.

普通のjsでの私の解決策:

let el=document.getElementById('el');
el.addEventListener('scroll', function (e) {
                if (el.scrollHeight - el.scrollTop - el.clientHeight<0) {
      console.log('Bottom')
    }
});
#el{
  width:300px;
  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>
0
Bakos Bence

受け入れられた答えが私のために働かなかったので、これは私の2セントです。

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