ユーザーが上にスクロールしない限り、オーバーフローdivを下にスクロールし続ける


222

大きさが300ピクセルしかないdivがあり、ページの読み込み時にコンテンツの下部までスクロールしたい。このdivにはコンテンツが動的に追加されており、下にスクロールし続ける必要があります。ユーザーが上にスクロールすることを決定した場合、ユーザーが再び下にスクロールするまで、下にジャンプしたくない

ユーザーが上にスクロールしない限り、一番下までスクロールしたままのdivを設定できます。ユーザーが下にスクロールすると、新しい動的コンテンツが追加された場合でも、一番下に表示される必要があります。これを作成するにはどうすればいいですか。


1
css位置topを使用して、それを下に保ち{position : relative; bottom:0;}ます。ユーザーがスクロールしたら、cssプロパティを削除します。
TCHdvlp 2013

答えを受け入れなかったので、聞きたいのですが、うまくいきましたか。
マンハッタン氏2013

4
達成したいチャットボックスのように聞こえる
Thielicious 2017

1
この質問の初心者は、2020年にcss snapを試してみてください。
wener

回答:


136

これはあなたを助けるかもしれません:

var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;

[編集]、コメントに一致させる...

function updateScroll(){
    var element = document.getElementById("yourDivID");
    element.scrollTop = element.scrollHeight;
}

コンテンツが追加されるたびに、関数updateScroll()を呼び出すか、タイマーを設定します。

//once a second
setInterval(updateScroll,1000);

ユーザーが移動しなかった場合にのみ更新する場合:

var scrolled = false;
function updateScroll(){
    if(!scrolled){
        var element = document.getElementById("yourDivID");
        element.scrollTop = element.scrollHeight;
    }
}

$("#yourDivID").on('scroll', function(){
    scrolled=true;
});

3
これはページの読み込み時に下までスクロールしますが、ユーザーが上にスクロールしない限り、動的コンテンツが追加されたときに下にとどまる必要があります。
Robert E. McIntosh 2013

12
私が知る限り、ユーザーが下にスクロールしても動的スクロールは再び有効になりません...
TvE

@TvEサポートを追加することはできませんか?
Barkermn01 2015

6
悪い解決策。setIntervalこの穏やかな問題にaを追加する理由はありません。
エサンクリスト2018年

6
@ethancristしかし、あなたは代替案を提供しません...肩をすくめます。
ジャレットロイド

180

CSSでのみこれを機能させることができました。

トリックを使用することですdisplay: flex;し、flex-direction: column-reverse;

ブラウザは下部を上部と同様に扱います。ターゲットとするブラウザーがサポートしていると仮定すると、flex-box唯一の注意点は、マークアップの順序が逆でなければならないことです。

これが実際の例です。https://codepen.io/jimbol/pen/YVJzBg


42
余分なラッパーを追加overflow:auto; display:flex; flex-direction:column-reverse;し、内部ラッパーの代わりに外部ラッパーに適用することで、コンテンツを逆にする必要を回避できます。
Nathan Arthur

6
JavaScriptを必要としないため、おそらく最良のソリューションです。
アミットクマールカレ2017年

3
@NathanArthur u da real mvp
php_nub_qq 2017

13
@NathanArthur実際、コンテナーの下にdivを追加してすべてを元に戻す場合
Coo

6
残念ながら、このソリューションはFirefoxでは機能しないようです:(
Stuart

166

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

次の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の不正確さで投げました。したがってisScrolledToBottom、スクロールバーが下から1pxの場合でもtrueになります。これは、自分にとって適切と思われるものに設定できます。

次に、要素の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>


22
これは、実際には、前述の質問を解決する唯一のソリューションです。そして、正解としてマークされている必要があります。
preezzzy、2015

1
@dotnetCarpenter:まるで必要なように見えますif(!isScrolledToBottom):テストは私には間違っているように見えます(そして、修正するまで私のコードでは機能しませんでした)。
luskwater '06

1
@luskwaterはfsfiddleに修正を提供できますか?の問題を理解できませんout.scrollHeight - out.clientHeight <= out.scrollTop + 1。CSSでパディングを使用していますか?
dotnetCarpenter 2017

2
これは私が探していたものです。そして、これがOPの質問に対する答えです。dotnetCarperterに感謝します。
Luis Menjivar 2017年

1
scrollTopを呼び出したときに誰かが0を取得している場合は、stackoverflow.comdocument.getScrollingElement / questions
Dane Jordan

29
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);

ライブデモ:http : //jsfiddle.net/KGfG2/


4
これはページの読み込み時に下までスクロールしますが、ユーザーが上にスクロールしない限り、動的コンテンツが追加されたときに下にとどまる必要があります。
Robert E. McIntosh 2013

これは完全に機能します。私は動的コンテンツで更新しており、スクロールは常に一番下にあります。
Andy Bajka

14
$('#div1').scrollTop($('#div1')[0].scrollHeight);

Or animated:

$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);

1
これはページの読み込み時に下までスクロールしますが、ユーザーが上にスクロールしない限り、動的コンテンツが追加されたときに下にとどまる必要があります。
Robert E. McIntosh 2013

これは、divが最初のショットで大きくなる場合には機能しません。たとえば、Angular-js、react js、Meteor Blazeテンプレートの読み込みでは、これは機能しません。
Ankur Soni、2018年

これでうまくいきました。問題のdivが一定の高さにとどまる場合は問題なく動作すると思います。動的な高さでテストしていません。
doij790

10

あなたが使用することができます2020年には、CSSをスナップが、クロム81の前に、レイアウトの変更がされますないトリガーの再スナップ純粋なCSSは、UIは、チャットもあなたがチェックすることができ、クロム81上で動作することができます私の使用のCSSスナップを

このデモは、表示されている場合は最後の要素をスナップします。下にスクロールして、効果を確認します。

.container {
  overflow-y: scroll;
  overscroll-behavior-y: contain;
  scroll-snap-type: y mandatory;
}

.container > div > div:last-child {
  scroll-snap-align: end;
}

.container > div > div {
  background: lightgray;
  height: 3rem;
  font-size: 1.5rem;
}
.container > div > div:nth-child(2n) {
  background: gray;
}
<div class="container" style="height:6rem">
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
</div>

ここに画像の説明を入力してください


5

.cont{
height: 100px;
overflow-x: hidden;
overflow-y: auto;
transform: rotate(180deg);
direction:rtl;
text-align:left;
}
ul{
overflow: hidden;
transform: rotate(180deg);
}
<div class="cont"> 
 <ul>
   <li>0</li>
   <li>1</li>
   <li>2</li>
   <li>3</li>
   <li>4</li>
   <li>5</li>
   <li>6</li>
   <li>7</li>
   <li>8</li>
   <li>9</li>
   <li>10</li>  
 </ul>
</div>

  1. Run code snippet効果を確認します。(PS:Run code snippet動作しない場合は、これを試してください:https : //jsfiddle.net/Yeshen/xm2yLksu/3/

  2. それがどのように働きますか:

デフォルトのオーバーフローは上から下へのスクロールです。

transform: rotate(180deg) 動的ブロックを下から上にスクロールまたはロードできます。

  1. オリジナルのアイデア:

https://blog.csdn.net/yeshennet/article/details/88880252


コードがOPの質問をどのように解決するかについての説明を追加してください
jro

1、追加の紹介を追加しました。2、Run code snippet直接、効果を見てください。
yisheng wu

実行コードスニペットボタンが表示されません。フォーマットを確認する
jro

それは素晴らしいことです。回答にリンクを含めてください
jro

2
非常にクリエイティブなソリューション。ただし、マウスのスクロールホイールの通常の操作が逆になります。上に移動するには、「下」にスクロールする必要があり、その逆も同様です。
mfluehr

3
$('#yourDivID').animate({ scrollTop: $(document).height() }, "slow");
return false;

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


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で動作します。


2

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

ただし、非常に残念なことに、これは安定した解決策ではありません。クロム(上記のdotnetCarpenterで説明されている1-pxの問題が原因である可能性があります)では、scrollTopユーザーが操作しなくても(要素を追加すると)、1ピクセルずつ正しく動作しません。を設定することはできますがscrollTop = scrollHeight - clientHeight、別の要素が追加されたときにdivの位置が維持されます。

つまり、簡単に言うと、少量のJavascript(ため息)を追加することでこれを修正し、すべての要件を満たします。

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

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

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

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


2

これは、Ryan Huntのブログ投稿に基づくソリューションです。これはoverflow-anchor、スクロールされたコンテンツの下部にある要素にスクロール位置を固定するCSSプロパティに依存します。

const messages = [
  'Expect rain today.',
  'Tomorrow will be sunny.',
  'Snow is coming next week.',
  'Hailstorms are imminent.',
];

function addMessage() {
  const $message = document.createElement('div');
  $message.className = 'message';
  $message.innerText = messages[(Math.random() * messages.length) | 0];
  $messages.insertBefore($message, $anchor);

  // Trigger the scroll pinning when the scroller overflows
  if (!overflowing) {
    overflowing = isOverflowing($scroller);
    $scroller.scrollTop = $scroller.scrollHeight;
  }
}

function isOverflowing($el) {
  return $el.scrollHeight > $el.clientHeight;
}

const $scroller = document.querySelector('.scroller');
const $messages = document.querySelector('.messages');
const $anchor = document.querySelector('.anchor');
let overflowing = false;

setInterval(addMessage, 1000);
.scroller {
  overflow: auto;
  height: 90vh;
  max-height: 11em;
  background: #555;
}

.messages > * {
  overflow-anchor: none;
}

.anchor {
  overflow-anchor: auto;
  height: 1px;
}

.message {
  margin: .3em;
  padding: .5em;
  background: #eee;
}
<section class="scroller">
  <div class="messages">
    <div class="anchor"></div>
  </div>
</section>

overflow-anchorこのソリューションは現在、すべてのブラウザでは動作しませんので、Safariやエッジで、現在の仕事をしません。


1

あなたはこのようなものを使うことができます、

var element = document.getElementById("yourDivID");
window.scrollTo(0,element.offsetHeight);

説明してください!
SzabolcsPáll19年

1.scrollToはウィンドウ全体を特定の座標にスクロールするメソッドです.2.offsetHeightは要素の高さを与えるため、上記のコードの2行目は、何かを割り当てている間、ウィンドウを下にスクロールし続けます。
Yashesh Chauhan

0

これが私がそれに取り組んだ方法です。私のdivの高さは650pxです。スクロールの高さが下部から150px以内であれば、自動スクロールすることにしました。それ以外の場合は、ユーザーに任せます。

if (container_block.scrollHeight - container_block.scrollTop < 800) {
                    container_block.scrollTo(0, container_block.scrollHeight);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.