사용자가 위로 스크롤하지 않으면 overflow div를 맨 아래로 스크롤 한 상태로 유지


224

300 픽셀 크기의 div가 있으며 페이지가 내용의 맨 아래로 스크롤 될 때 원합니다. 이 div에는 동적으로 콘텐츠가 추가되어 계속 스크롤되어 있어야합니다. 이제 사용자가 위로 스크롤하기로 결정한 경우 사용자가 다시 아래로 스크롤 할 때까지 맨 아래로 다시 이동하고 싶지 않습니다.

사용자가 위로 스크롤하지 않으면 사용자가 맨 아래로 스크롤하지 않으면 맨 아래로 스크롤 된 div를 가질 수 있습니까? 그리고 사용자가 맨 아래로 다시 스크롤하면 새로운 동적 내용이 추가 된 경우에도 맨 아래에 있어야합니다. 이것을 만들어내는 방법은 무엇입니까?


1
CSS 위치 상단을 사용하여 하단에 유지하십시오 {position : relative; bottom:0;}. 사용자가 스크롤하면 css 속성을 제거하십시오.
— TCHdvlp

당신이 대답을 받아들이지 않았기 때문에 묻고 싶습니다.
— Mr.Manhattan

4
달성하고자하는
— 대화 상자

1
이 질문을 처음 접하려면 2020 년에 CSS 스냅 을 시도해야합니다 .
— 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

12
내가 알 수있는 한 이것은 사용자가 맨 아래로 다시 스크롤 할 때 동적 스크롤을 다시 활성화하지 않는다 ...
— TvE

@TvE 지원을 추가 할 수 없습니까?
— Barkermn01

6
나쁜 해결책. setInterval이 가벼운 문제 를 추가 할 이유가 없습니다 .
— ethancrist

6
@ethancrist 그러나, 당신은 대안을 제공하지 않습니다 ... 어깨를 으 s.
— Jarett Lloyd

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
아마도 자바 스크립트가 필요하지 않기 때문에 가장 좋은 해결책 일 것입니다.
— Amit Kumar Khare

3
@NathanArthur u da real mvp
— php_nub_qq 1

13
@NathanArthur 사실, 컨테이너 아래에 div를 추가하여 모든 것을 취소하려면 codepen.io/anon/pen/pdrLEZ
— 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은 상단이고 최대는 요소의 scrollHeight에서 요소 높이를 뺀 값입니다. 스크롤 막대를 사용할 때 스크롤 막대를 맨 아래로 내리는 것이 어려울 수 있습니다 (Chrome에서는 저에게 있습니다). 그래서 나는 1px 부정확성을 던졌습니다. 그래서 isScrolledToBottom스크롤이 바닥에서 1 픽셀의 경우에도 마찬가지 일 것이다. 당신은 당신에게 맞는 느낌으로 이것을 설정할 수 있습니다.

그런 다음 단순히 요소의 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

1
@dotnetCarpenter : 그것은 당신이 필요 것처럼 나에게 보이는 if(!isScrolledToBottom)테스트가 나에게 잘못 보인다 (과에서 일을하지 않았다 : 내 나는 그것을 고정 될 때까지 코드).
— luskwater

1
@luskwater 당신은 당신의 수정으로 fsfiddle을 제공 할 수 있습니까? 의 문제를 이해하지 못합니다 out.scrollHeight - out.clientHeight <= out.scrollTop + 1. CSS에서 패딩을 사용하고 있습니까?
— dotnetCarpenter

2
이것이 내가 찾던 것입니다. 그리고 이것은 OP가 묻는 질문에 대한 답변입니다. dotnetCarperter에게 감사합니다.
— Luis Menjivar

1
사람이 공을 받고 있다면 그들은 내가 사용하는 것이 좋습니다, scrollTop를 호출 할 때 document.getScrollingElement여기 제안 : stackoverflow.com/questions/36227559/scrolltop-always-returns-0/...
— 덴마크 요르단

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

라이브 데모 : http://jsfiddle.net/KGfG2/


4
이것은 페이지로드시 맨 아래로 스크롤되지만 사용자가 위로 스크롤하지 않으면 동적 내용이 추가 될 때 맨 아래에 있어야합니다.
— Robert E. McIntosh

이것은 완벽하게 작동합니다. 동적 콘텐츠로 업데이트 중이며 스크롤이 항상 맨 아래에 있습니다.
— 앤디

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

Or animated:

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

1
이것은 페이지로드시 맨 아래로 스크롤되지만 사용자가 위로 스크롤하지 않으면 동적 내용이 추가 될 때 맨 아래에 있어야합니다.
— Robert E. McIntosh

첫 번째 샷에서 div가 많이 자라면 작동하지 않습니다. 예를 들어 Angular-js에서는 반응 js, Meteor Blaze 템플릿 로딩이 작동하지 않습니다.
— Ankur Soni

이것은 나를 위해 일했습니다. 문제의 div가 일정한 높이를 유지하면 제대로 작동한다고 생각합니다. 동적 높이로 테스트하지 않았습니다.
— doij790

11

2020 년, 당신이 사용할 수있는 CSS 스냅을 하지만, 크롬 81 레이아웃 변경하기 전에 것입니다 트리거 다시 스냅하지 하는 UI를 채팅 순수 CSS를 크롬 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사용하여 높이에서 ScrollTop 위치를 계산하여 $(document).height()동적 내용이 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와 크롬에서 작동합니다.


2

Jim Hall의 답변은 스크롤 할 때 실제로 맨 아래로 스크롤되지 않지만 순수한 CSS이기 때문에 선호됩니다.

그러나 불행히도 이것은 안정적인 솔루션이 아닙니다. 크롬에서 (위의 dotnetCarpenter가 설명한 scrollTop1 픽셀 문제로 인해) 사용자 상호 작용 (요소 추가시)이 없어도 1 픽셀만큼 부정확하게 작동합니다. 을 설정할 수는 scrollTop = scrollHeight - clientHeight있지만 다른 요소가 추가 될 때 div 위치를 유지합니다. 즉, "자체를 맨 아래에 유지"기능이 더 이상 작동하지 않습니다.

즉, 소량의 Javascript (sigh)를 추가하면이 문제가 해결되고 모든 요구 사항이 충족됩니다.

https://codepen.io/anon/pen/pdrLEZ 와 같은 것 (예 : Coo의 예) 및 요소를 목록에 추가 한 후 다음 사항도 수행하십시오.

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

여기서 29는 한 줄의 높이입니다.

따라서 사용자가 반 줄을 스크롤하면 (가능한 경우) Javascript는이를 무시하고 맨 아래로 스크롤합니다. 그러나 이것은 무시할 수 있다고 생각합니다. 그리고 Chrome 1 px를 수정합니다.


2

Ryan Hunt의 블로그 게시물을 기반으로 한 솔루션이 있습니다. overflow-anchorCSS 속성 에 따라 스크롤되는 위치를 스크롤 된 내용의 맨 아래에있는 요소에 고정시킵니다.

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이 솔루션은 현재 모든 브라우저에서 작동하지 않도록, 사파리 또는 Edge 현재 일을하지 않습니다.


1

이런 식으로 사용할 수 있습니다

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

설명해주세요!
— Szabolcs Páll

1. scrollTo는 전체 창을 특정 좌표로 스크롤하는 메소드입니다.
— 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.