337

大きさが 300 ピクセルしかない div があり、ページが読み込まれたときにコンテンツの一番下までスクロールしたいと考えています。この div にはコンテンツが動的に追加されており、ずっと下にスクロールする必要があります。ユーザーが上にスクロールすることを決定した場合、ユーザーがもう一度下にスクロールするまで、下に戻りたくありません

ユーザーが上にスクロールしない限り下にスクロールしたままの div を持つことは可能ですか。これを作成するにはどうすればよいでしょうか。

4

18 に答える 18

189

私はこれを実装したばかりで、おそらく私のアプローチを使用できます。

次の HTML があるとします。

<div id="out" style="overflow:auto"></div>

次に、下までスクロールしたかどうかを確認できます。

var out = document.getElementById("out");
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;

scrollHeightは、オーバーフローによる非表示領域を含む要素の高さを示します。clientHeightは、CSS の高さ、または別の言い方をすれば、要素の実際の高さを示します。どちらのメソッドも高さを なしmarginで返すので、心配する必要はありません。scrollTopは、垂直スクロールの位置を示します。0 は上であり、max は要素の scrollHeight から要素の高さ自体を引いたものです。スクロールバーを使用する場合、スクロールバーを一番下まで移動するのが難しい場合があります (私にとっては Chrome にありました)。だから私は1pxの不正確さを投げました。スクロールバーが下から1pxisScrolledToBottomの位置にある場合でも同様です。これは、自分に適したものに設定できます。

次に、要素の scrollTop を一番下に設定するだけです。

if(isScrolledToBottom)
    out.scrollTop = out.scrollHeight - out.clientHeight;

概念を示すためにフィドルを作成しました: http://jsfiddle.net/dotnetCarpenter/KpM5j/

isScrolledToBottom編集:がいつなのかを明確にするためにコード スニペットを追加しましたtrue

スクロールバーを下に固定

const out = document.getElementById("out")
let c = 0

setInterval(function() {
    // allow 1px inaccuracy by adding 1
    const isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1

    const newElement = document.createElement("div")

    newElement.textContent = format(c++, 'Bottom position:', out.scrollHeight - out.clientHeight,  'Scroll position:', out.scrollTop)

    out.appendChild(newElement)

    // scroll to bottom if isScrolledToBottom is true
    if (isScrolledToBottom) {
      out.scrollTop = out.scrollHeight - out.clientHeight
    }
}, 500)

function format () {
  return Array.prototype.slice.call(arguments).join(' ')
}
#out {
    height: 100px;
}
<div id="out" style="overflow:auto"></div>
<p>To be clear: We want the scrollbar to stick to the bottom if we have scrolled all the way down. If we scroll up, then we don't want the content to move.
</p>

于 2014-01-11T20:24:04.123 に答える
17
$('#div1').scrollTop($('#div1')[0].scrollHeight);

Or animated:

$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);
于 2013-09-04T13:01:40.900 に答える
3
$('#yourDivID').animate({ scrollTop: $(document).height() }, "slow");
return false;

#yourDivIDこれにより、プロパティを使用して高さから ScrollTop 位置が計算される$(document).height()ため、動的コンテンツが div に追加された場合でも、スクローラーは常に下の位置になります。お役に立てれば。ただし、上にスクロールしてマウス ポインターをスクローラーから離しても、小さなバグがあり、自動的に一番下の位置に移動します。誰かがそれを修正できれば、それもいいでしょう。

于 2015-02-15T11:32:23.777 に答える
3

上位 2 つの回答が機能しませんでした。他の回答はどれも役に立ちませんでした。そこで、Reddit r/forhireUpworkから 3 人に 30 ドルを支払い、本当に良い回答を得ました。この回答により、90 ドル節約できます。



Justin Hundley / The Site Bros のソリューション

HTML

<div id="chatscreen">
  <div id="inner">
  
  </div>
</div>

CSS

#chatscreen {
  width: 300px;
  overflow-y: scroll;
  max-height:100px;
}

Javascript

$(function(){
    var scrolled = false;
  var lastScroll = 0;
  var count = 0;
    $("#chatscreen").on("scroll", function() {
    var nextScroll = $(this).scrollTop();

    if (nextScroll <= lastScroll) {
        scrolled = true;
    }
    lastScroll = nextScroll;
    
    console.log(nextScroll, $("#inner").height())
    if ((nextScroll + 100) == $("#inner").height()) {
        scrolled = false;
    }
  });
 
  function updateScroll(){
      if(!scrolled){
          var element = document.getElementById("chatscreen");
          var inner = document.getElementById("inner");
          element.scrollTop = inner.scrollHeight;
      }
  }

  // Now let's load our messages
  function load_messages(){
      $( "#inner" ).append( "Test" + count + "<br/>" );
      count = count + 1;
      updateScroll();
  }

    setInterval(load_messages,300); 
});

サイト ブロスのソリューションをプレビューする

ポートフォリオ



Lermex / Sviatoslav Chumakovのソリューション

HTML

<div id="chatscreen">

</div>

CSS

#chatscreen {
  height: 300px;
  border: 1px solid purple;
  overflow: scroll;
}

Javascript

$(function(){
var isScrolledToBottom = false;
// Now let's load our messages
function load_messages(){
    $( "#chatscreen" ).append( "<br>Test" );
    updateScr();
}

var out = document.getElementById("chatscreen");
var c = 0;

$("#chatscreen").on('scroll', function(){
        console.log(out.scrollHeight);
    isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 10;
});

function updateScr() {
        // allow 1px inaccuracy by adding 1
    //console.log(out.scrollHeight - out.clientHeight,  out.scrollTop + 1);
    var newElement = document.createElement("div");

    newElement.innerHTML = c++;
    out.appendChild(newElement);
    
    console.log(isScrolledToBottom);

    // scroll to bottom if isScrolledToBotto
    if(isScrolledToBottom) {out.scrollTop = out.scrollHeight - out.clientHeight; }
}

var add = setInterval(updateScr, 1000);

setInterval(load_messages,300); // change to 300 to show the latest message you sent after pressing enter // comment this line and it works, uncomment and it fails
                                // leaving it on 1000 shows the second to last message
setInterval(updateScroll,30);
});

Sviatoslav のソリューションのプレビュー

ポートフォリオ



イゴール・ルシノフのソリューション

HTML

<div id="chatscreen"></div>

CSS

#chatscreen {
  height: 100px;
  overflow: scroll;
  border: 1px solid #000;
}

Javascript

$(function(){

// Now let's load our messages
function load_messages(){
    $( "#chatscreen" ).append( "<br>Test" );
}

var out = document.getElementById("chatscreen");
var c = 0;
var add = setInterval(function() {
    // allow 1px inaccuracy by adding 1
    var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
    load_messages();

    // scroll to bottom if isScrolledToBotto
    if(isScrolledToBottom) {out.scrollTop = out.scrollHeight - out.clientHeight; }
}, 1000);
setInterval(updateScroll,30);
});

Igor のソリューションのプレビュー

ポートフォリオ

于 2020-12-10T06:14:50.023 に答える
2
//Make sure message list is scrolled to the bottom
var container = $('#MessageWindowContent')[0];
var containerHeight = container.clientHeight;
var contentHeight = container.scrollHeight;

container.scrollTop = contentHeight - containerHeight;

dotnetCarpenter の回答に基づく私のバージョンは次のとおりです。私のアプローチは純粋な jQuery であり、変数に名前を付けて物事を少し明確にしています。何が起こっているのかというと、コンテンツの高さがコンテナーよりも大きい場合、目的の結果を得るために余分な距離を下にスクロールします。

IE と chrome で動作します。

于 2016-02-19T14:49:38.643 に答える
2

このようなものを使用できます。

var element = document.getElementById("yourDivID");
window.scrollTo(0,element.offsetHeight);
于 2019-11-27T08:46:38.550 に答える
2

ジム・ホールの答えは、上にスクロールしても実際には下までスクロールしないため、望ましいものですが、純粋なCSSでもあります。

残念ながら、これは安定した解決策ではありません。クロムでは (おそらく、上記の dotnetCarpenter で説明されている 1 ピクセルの問題が原因で)、scrollTopユーザーの操作がなくても (要素の追加時に) 1 ピクセルずつ不正確に動作します。を設定することはできますがscrollTop = scrollHeight - clientHeight、それにより、別の要素が追加されたときに div が所定の位置に保持されます。つまり、「最下部に保持する」機能が機能しなくなります。

要するに、少量の Javascript (ため息) を追加すると、これが修正され、すべての要件が満たされます。

https://codepen.io/anon/pen/pdrLEZのようなもの(Coo による例)、およびリストに要素を追加した後、次のことも行います。

container = ...
if(container.scrollHeight - container.clientHeight - container.scrollTop <= 29) {
    container.scrollTop = container.scrollHeight - container.clientHeight;
}

ここで、29 は 1 行の高さです。

そのため、ユーザーが半行上にスクロールすると (それが可能な場合でも?)、Javascript はそれを無視して一番下までスクロールします。でも、これは仕方のないことだと思います。そして、Chrome 1 px のものを修正します。

于 2018-09-27T07:21:36.700 に答える
0

これが私がそれにアプローチした方法です。私のdivの高さは650pxです。スクロールの高さが下から 150px 以内の場合は自動スクロールすることにしました。それ以外の場合は、ユーザーに任せてください。

if (container_block.scrollHeight - container_block.scrollTop < 800) {
                    container_block.scrollTo(0, container_block.scrollHeight);
}
于 2019-08-30T02:15:11.370 に答える