사용자가 위로 스크롤하지 않는 한 오버플로 div를 아래로 스크롤 유지
300픽셀밖에 안 되는 디바를 가지고 있는데, 페이지가 로딩될 때 콘텐츠의 맨 아래까지 스크롤을 하고 싶습니다.이 div에는 콘텐츠가 동적으로 추가되어 있으며 아래로 스크롤된 상태를 유지해야 합니다.이제 사용자가 위로 스크롤하기로 결정했을 때 사용자가 다시 아래로 스크롤할 때까지 아래로 다시 이동하지 않았으면 합니다.
사용자가 위로 스크롤하지 않는 한 아래로 스크롤되는 div를 가질 수 있으며, 사용자가 아래로 스크롤할 때 새로운 동적 콘텐츠가 추가되어도 하위를 유지할 필요가 있습니까?이걸 어떻게 만들까?
저는 이것을 CSS와만 연계할 수 있었습니다.
요령은 사용법이다.display: flex; ★★★★★★★★★★★★★★★★★」flex-direction: column-reverse;
브라우저는 맨 아래를 맨 위처럼 취급합니다.하는 한다고 가정합니다.flex-box단, 마크업이 역순으로 되어 있을 필요가 있다는 점만 주의해 주십시오.
여기 작업 예가 있습니다.https://codepen.io/jimbol/pen/YVJzBg
도움이 될 수 있습니다.
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;
});
저는 이것을 방금 실장했습니다만, 아마 제 어프로치를 이용하실 수 있을 것입니다.
예를 들어 다음과 같은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;
스크롤 높이는 오버플로로 인해 보이지 않는 영역을 포함하여 요소의 높이를 제공합니다.client Height는 CSS 높이를 나타내거나 다른 방법으로 요소의 실제 높이를 나타냅니다.두 방법 모두 다음을 제외하고 높이를 반환합니다.margin그 점은 걱정하지 않아도 됩니다.scroll Top에서는 세로 스크롤 위치를 알 수 있습니다.0은 맨 위, max는 요소의 스크롤 높이에서 요소 높이 자체를 뺀 값입니다.스크롤바를 사용할 때 스크롤바를 아래까지 가져가기 어려울 수 있습니다(Chrome에서 사용).정확도가 1px나 떨어졌어요.그렇게isScrolledToBottom1px로 하다당신이 옳다고 생각하는 대로 이 일을 할 수 있어요.
그리고 요소의 스크롤 상단을 하단으로 설정하기만 하면 됩니다.
if(isScrolledToBottom)
out.scrollTop = out.scrollHeight - out.clientHeight;
컨셉을 보여주기 위해 바이올린을 만들었습니다.http://jsfiddle.net/dotnetCarpenter/KpM5j/
EDIT:하여 언제인지 할 수 .isScrolledToBottomtrue.
스크롤 막대를 바닥에 고정합니다.
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>
2020년에는 css snap을 사용할 수 있지만, Chrome 81 이전에는 레이아웃 변경으로 재스냅이 트리거되지 않습니다.Chrome 81에서는 순수 css chat UI가 동작합니다.또, Can I use CSS snap도 체크할 수 있습니다.
이 데모에서는 마지막 요소가 표시되는 경우 아래로 스크롤하여 효과를 확인합니다.
.container {
overflow-y: scroll;
overscroll-behavior-y: contain;
scroll-snap-type: y proximity;
}
.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>
편집
scroll-snap-type: y proximity; 위로 수 있습니다 , 더 쉽게 위로 스크롤할 수 있습니다.
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);
라이브 데모: http://jsfiddle.net/KGfG2/
$('#div1').scrollTop($('#div1')[0].scrollHeight);
Or animated:
$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);
.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>
Run code snippet(PS: ★★★★Run code snippet가 동작하지 않습니다.https://jsfiddle.net/Yeshen/xm2yLksu/3/ 를 사용해 주세요.구조:
기본 오버플로는 위에서 아래로 스크롤합니다.
transform: rotate(180deg)스크롤하거나 다이내믹 블록을 아래에서 위로 로드할 수 있습니다.
- 오리지널 아이디어:
https://blog.csdn.net/yeshennet/article/details/88880252
Jim Halls의 솔루션과 코멘트를 기반으로 합니다.https://stackoverflow.com/a/44051405/9208887 를 참조해 주세요.
에 ''라는 했습니다.flex 1 1 0%컨테이너가 가득 차지 않을 때 컨테이너의 맨 위에서 텍스트가 시작되도록 합니다.
// just to add some numbers, so we can see the effect
// the actual solution requires no javascript
let num = 1001;
const container = document.getElementById("scroll-container");
document.getElementById("adder").onclick = () =>
container.append(
Object.assign(document.createElement("div"), {
textContent: num++
})
);
.scroll-wrapper {
height: 100px;
overflow: auto;
display: flex;
flex-direction: column-reverse;
border: 1px solid black;
}
.scroll-start-at-top {
flex: 1 1 0%;
}
<div class="scroll-wrapper">
<span class="scroll-start-at-top"></span>
<div id="scroll-container">
<div>1000</div>
</div>
</div>
<button id="adder">Add Text</button>
다음은 Ryan Hunt가 블로그에 올린 글을 바탕으로 한 해결책입니다.에 따라 다릅니다.overflow-anchorCSS 속성: 스크롤된 콘텐츠 하단의 요소에 스크롤 위치를 고정합니다.
function addMessage() {
const $message = document.createElement('div');
$message.className = 'message';
$message.innerText = `Random number = ${Math.ceil(Math.random() * 1000)}`;
$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>
Safari에서는 현재 동작하지 않습니다.
상위 2개의 답변을 얻을 수 없었고, 다른 답변은 전혀 도움이 되지 않았습니다.그래서 나는 Reddit r/forhire와 Upwork에서 3명에게 $30을 지불하고 정말 좋은 답을 얻었다.이 답변으로 90달러를 절약할 수 있습니다.
Justin Hundley / 사이트 브라더스 솔루션
HTML
<div id="chatscreen">
<div id="inner">
</div>
</div>
CSS
#chatscreen {
width: 300px;
overflow-y: scroll;
max-height:100px;
}
자바스크립트
$(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);
});
레르멕스/스비아토슬라프 추마코프 해법
HTML
<div id="chatscreen">
</div>
CSS
#chatscreen {
height: 300px;
border: 1px solid purple;
overflow: scroll;
}
자바스크립트
$(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);
});
이고르 루시노프의 솔루션
HTML
<div id="chatscreen"></div>
CSS
#chatscreen {
height: 100px;
overflow: scroll;
border: 1px solid #000;
}
자바스크립트
$(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);
});
$('#yourDivID').animate({ scrollTop: $(document).height() }, "slow");
return false;
가 ScrollTop의 됩니다.#yourDivID$(document).height()동적 내용이 div에 추가되더라도 스크롤러가 항상 맨 아래 위치에 있도록 합니다.이게 도움이 됐으면 좋겠다.그러나 스크롤러를 위로 스크롤하여 마우스 포인터를 스크롤에서 떼도 자동으로 맨 아래 위치에 오기도 합니다.누군가 그것 또한 고칠 수 있다면 좋을 것이다.
//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 및 크롬으로 동작합니다.
Jim Hall의 답변은 선호됩니다.왜냐하면 스크롤업 시 맨 아래로 스크롤되지 않지만 순수한 CSS이기도 하기 때문입니다.
그러나 매우 유감스럽지만 이는 안정적인 솔루션이 아닙니다.위의 일 수 있습니다), ""dotnetCarpenter" ("1-px")scrollTop(요소 추가 시) 사용자의 조작이 없어도 1픽셀의 부정확한 동작을 합니다. 설정할 수 .scrollTop = scrollHeight - clientHeight단, 다른 요소가 추가되어도 div는 제자리에 유지됩니다.밑바닥을 지켜라.
즉, 소량의 Javascript(sigh)를 추가하면 이 문제가 해결되어 모든 요건을 충족할 수 있습니다.
예를 들어 https://codepen.io/anon/pen/pdrLEZ this(Coo에 의해 제공됨) 및 목록에 요소를 추가한 후 다음과 같은 것이 있습니다.
container = ...
if(container.scrollHeight - container.clientHeight - container.scrollTop <= 29) {
container.scrollTop = container.scrollHeight - container.clientHeight;
}
여기서 29는 한 줄의 높이입니다.
따라서 사용자가 반 줄 위로 스크롤하면(가능하다면?), Javascript는 이를 무시하고 아래로 스크롤합니다.하지만 나는 이것이 무시할 수 있다고 생각한다.그리고 Chrome 1 px를 고정합니다.
이런 거 써도 되는데
var element = document.getElementById("yourDivID");
window.scrollTo(0,element.offsetHeight);
다음은 당신이 필요로 하는 것을 한다(저는 최선을 다했고, 그 과정에서 구글 검색도 많이 했습니다).
<html>
<head>
<script>
// no jquery, or other craziness. just
// straight up vanilla javascript functions
// to scroll a div's content to the bottom
// if the user has not scrolled up. Includes
// a clickable "alert" for when "content" is
// changed.
// this should work for any kind of content
// be it images, or links, or plain text
// simply "append" the new element to the
// div, and this will handle the rest as
// proscribed.
let scrolled = false; // at bottom?
let scrolling = false; // scrolling in next msg?
let listener = false; // does element have content changed listener?
let contentChanged = false; // kind of obvious
let alerted = false; // less obvious
function innerHTMLChanged() {
// this is here in case we want to
// customize what goes on in here.
// for now, just:
contentChanged = true;
}
function scrollToBottom(id) {
if (!id) { id = "scrollable_element"; }
let DEBUG = 0; // change to 1 and open console
let dstr = "";
let e = document.getElementById(id);
if (e) {
if (!listener) {
dstr += "content changed listener not active\n";
e.addEventListener("DOMSubtreeModified", innerHTMLChanged);
listener = true;
} else {
dstr += "content changed listener active\n";
}
let height = (e.scrollHeight - e.offsetHeight); // this isn't perfect
let offset = (e.offsetHeight - e.clientHeight); // and does this fix it? seems to...
let scrollMax = height + offset;
dstr += "offsetHeight: " + e.offsetHeight + "\n";
dstr += "clientHeight: " + e.clientHeight + "\n";
dstr += "scrollHeight: " + e.scrollHeight + "\n";
dstr += "scrollTop: " + e.scrollTop + "\n";
dstr += "scrollMax: " + scrollMax + "\n";
dstr += "offset: " + offset + "\n";
dstr += "height: " + height + "\n";
dstr += "contentChanged: " + contentChanged + "\n";
if (!scrolled && !scrolling) {
dstr += "user has not scrolled\n";
if (e.scrollTop != scrollMax) {
dstr += "scroll not at bottom\n";
e.scroll({
top: scrollMax,
left: 0,
behavior: "auto"
})
e.scrollTop = scrollMax;
scrolling = true;
} else {
if (alerted) {
dstr += "alert exists\n";
} else {
dstr += "alert does not exist\n";
}
if (contentChanged) { contentChanged = false; }
}
} else {
dstr += "user scrolled away from bottom\n";
if (!scrolling) {
dstr += "not auto-scrolling\n";
if (e.scrollTop >= scrollMax) {
dstr += "scroll at bottom\n";
scrolled = false;
if (alerted) {
dstr += "alert exists\n";
let n = document.getElementById("alert");
n.remove();
alerted = false;
contentChanged = false;
scrolled = false;
}
} else {
dstr += "scroll not at bottom\n";
if (contentChanged) {
dstr += "content changed\n";
if (!alerted) {
dstr += "alert not displaying\n";
let n = document.createElement("div");
e.append(n);
n.id = "alert";
n.style.position = "absolute";
n.classList.add("normal-panel");
n.classList.add("clickable");
n.classList.add("blink");
n.innerHTML = "new content!";
let nposy = parseFloat(getComputedStyle(e).height) + 18;
let nposx = 18 + (parseFloat(getComputedStyle(e).width) / 2) - (parseFloat(getComputedStyle(n).width) / 2);
dstr += "nposx: " + nposx + "\n";
dstr += "nposy: " + nposy + "\n";
n.style.left = nposx;
n.style.top = nposy;
n.addEventListener("click", () => {
dstr += "clearing alert\n";
scrolled = false;
alerted = false;
contentChanged = false;
n.remove();
});
alerted = true;
} else {
dstr += "alert already displayed\n";
}
} else {
alerted = false;
}
}
} else {
dstr += "auto-scrolling\n";
if (e.scrollTop >= scrollMax) {
dstr += "done scrolling";
scrolling = false;
scrolled = false;
} else {
dstr += "still scrolling...\n";
}
}
}
}
if (DEBUG && dstr) console.log("stb:\n" + dstr);
setTimeout(() => { scrollToBottom(id); }, 50);
}
function scrollMessages(id) {
if (!id) { id = "scrollable_element"; }
let DEBUG = 1;
let dstr = "";
if (scrolled) {
dstr += "already scrolled";
} else {
dstr += "got scrolled";
scrolled = true;
}
dstr += "\n";
if (contentChanged && alerted) {
dstr += "content changed, and alerted\n";
let n = document.getElementById("alert");
if (n) {
dstr += "alert div exists\n";
let e = document.getElementById(id);
let nposy = parseFloat(getComputedStyle(e).height) + 18;
dstr += "nposy: " + nposy + "\n";
n.style.top = nposy;
} else {
dstr += "alert div does not exist!\n";
}
} else {
dstr += "content NOT changed, and not alerted";
}
if (DEBUG && dstr) console.log("sm: " + dstr);
}
setTimeout(() => { scrollToBottom("messages"); }, 1000);
/////////////////////
// HELPER FUNCTION
// simulates adding dynamic content to "chat" div
let count = 0;
function addContent() {
let e = document.getElementById("messages");
if (e) {
let br = document.createElement("br");
e.append("test " + count);
e.append(br);
count++;
}
}
</script>
<style>
button {
border-radius: 5px;
}
#container {
padding: 5px;
}
#messages {
background-color: blue;
border: 1px inset black;
border-radius: 3px;
color: white;
padding: 5px;
overflow-x: none;
overflow-y: auto;
max-height: 100px;
width: 100px;
margin-bottom: 5px;
text-align: left;
}
.bordered {
border: 1px solid black;
border-radius: 5px;
}
.inline-block {
display: inline-block;
}
.centered {
text-align: center;
}
.normal-panel {
background-color: #888888;
border: 1px solid black;
border-radius: 5px;
padding: 2px;
}
.clickable {
cursor: pointer;
}
</style>
</head>
<body>
<div id="container" class="bordered inline-block centered">
<div class="inline-block">My Chat</div>
<div id="messages" onscroll="scrollMessages('messages')">
test<br>
test<br>
test<br>
test<br>
test<br>
test<br>
test<br>
test<br>
test<br>
test<br>
</div>
<button onclick="addContent();">Add Content</button>
</div>
</body>
</html>
주의: 경보 위치를 조정해야 할 수 있습니다.nposx ★★★★★★★★★★★★★★★★★」nposy는, 양쪽 모두, 「」로 있습니다.scrollToBottom ★★★★★★★★★★★★★★★★★」scrollMessages★★★★★★★★★★★...
또, 서버상에서 호스트 되고 있는 자신의 작업 예에의 링크도 있습니다.https://night-stand.ca/jaretts_tests/chat_scroll.html
내가 접근한 방법은 이렇다.제 디바인 키는 650ppx입니다.스크롤 높이가 하단의 150px 이내이면 자동으로 스크롤하기로 했습니다.그 이외의 경우는, 유저에게 맡겨 주세요.
if (container_block.scrollHeight - container_block.scrollTop < 800) {
container_block.scrollTo(0, container_block.scrollHeight);
}
이 일을 해내는데 성공했어요.요령은 새 요소를 추가하기 전에 (a) 현재 div 사용자 스크롤 위치와 (b) div 스크롤 높이를 계산하는 것입니다.
a === b인 경우 새 요소를 추가하기 전에 사용자가 맨 아래에 있음을 알 수 있습니다.
let div = document.querySelector('div.scrollableBox');
let span = document.createElement('span');
span.textContent = 'Hello';
let divCurrentUserScrollPosition = div.scrollTop + div.offsetHeight;
let divScrollHeight = div.scrollHeight;
// We have the current scroll positions saved in
// variables, so now we can append the new element.
div.append(span);
if ((divScrollHeight === divCurrentUserScrollPosition)) {
// Scroll to bottom of div
div.scrollTo({ left: 0, top: div.scrollHeight });
}
Bootstrap 5도 똑같이 하려고 했어요.제가 쓰고 있는 페이지는 싱글윈도의 html 툴로, 2개의 컬럼에 스크롤 가능한 콘텐츠를 붙이고 싶었고, 1개는 로그이기 때문에 반대로 되어 있어야 합니다(다른 1개는 일부러 스크롤을 하지 않는 한).목록과 헤더도 맨 아래 앵커로 되어 있어 헤더를 스크롤 가능한 목록 바로 위에 유지하는 데 어려움이 있었습니다.
위의 예들 덕분에 나는 내가 무엇을 놓쳤는지 알 수 있었고 그것을 작동시키기 위한 적절한 수업 유형을 얻을 수 있었다.
여기 제 전체 예가 있습니다.내 실제 앱에는 클래스가 있는 다른 두 개의 세 번째 열이 남아 있다.mh-100 col overflow-auto맨 위에 붙일 제목이 없기 때문에 내부 행/열이 필요하지 않습니다(뷰포트가 너무 작으면 정상적으로 스크롤됩니다).및 또는 요소) .<li>항목을 반전 목록에 표시).
보다 작은 버전은 다음과 같습니다.
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<div class="vh-100 w-75 container-fluid">
<h1>2nd Level Scrolling Example</h1>
<div class="h-75 row align-items-end">
<div class="mh-100 col d-flex flex-column">
<div class="row align-items-end">
<div class="col"><h3>Normal scroll list, grow on top</h3></div>
</div>
<div class="row align-items-end overflow-auto">
<div class="mh-100 col">
<ul class="list-group">
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ut</li>
<li>tortor eu ex tincidunt pretium non eu nisl. Ut eu libero ac velit</li>
<li>ultricies dapibus. Donec id augue scelerisque, gravida est ut,</li>
<li>commodo sapien. Interdum et malesuada fames ac ante ipsum primis</li>
<li>in faucibus. Suspendisse volutpat fermentum finibus. Cras egestas</li>
<li>tempor tempor. Suspendisse potenti. Mauris ac tellus ultrices lectus</li>
<li>accumsan pellentesque. Nullam semper, nisi nec euismod ultrices, leo</li>
<li>sem bibendum sapien, in rutrum sapien massa id mi.</li>
</ul>
</div>
</div>
</div>
<div class="mh-100 col d-flex flex-column">
<div class="row align-items-end">
<div class="col"><h3>Reverse scroll list, grow on bottom</h3></div>
</div>
<div class="row align-items-end d-flex flex-column-reverse overflow-auto">
<div class="mh-100 col">
<ul class="list-group">
<li>sem bibendum sapien, in rutrum sapien massa id mi.</li>
<li>accumsan pellentesque. Nullam semper, nisi nec euismod ultrices, leo</li>
<li>tempor tempor. Suspendisse potenti. Mauris ac tellus ultrices lectus</li>
<li>in faucibus. Suspendisse volutpat fermentum finibus. Cras egestas</li>
<li>commodo sapien. Interdum et malesuada fames ac ante ipsum primis</li>
<li>ultricies dapibus. Donec id augue scelerisque, gravida est ut,</li>
<li>tortor eu ex tincidunt pretium non eu nisl. Ut eu libero ac velit</li>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ut</li>
</ul>
</div>
</div>
</div>
</div>
</div>
뷰포트 높이가 전체 콘텐츠보다 작을 경우 제목은 목록 맨 위에 있고 페이지 맨 아래에 있는 모든 항목(실제로 뷰포트 높이의 75%)이 있어야 합니다. 그러나 이 예에서는 제목이 설계한 공간을 차지하지 않습니다.
NB: 저는 웹 개발자가 아닙니다.일상 업무에 편리한 HTML 기반의 툴을 쓰고 있기 때문에 코멘트는 매우 환영합니다.
가장 사용하기 쉬운 솔루션은 접근법과 약간의 Javascript를 결합하는 것입니다.이전 솔루션 자체의 문제는 스냅이 너무 강해서 스냅에서 벗어나려면 멀리 스크롤해야 한다는 것입니다.
대신 컨테이너가 아래로 스크롤되는 동안 스냅 다이내믹을 사용하고 사용자가 특정 임계값을 초과하여 스크롤하면 비활성화 시킬 수 있습니다.
이 솔루션에는 점진적인 확장이라는 이점이 있습니다.사용자가 Javascript를 비활성화하면 CSS만의 접근법으로 돌아갑니다.
const container = document.getElementById("container");
const snap = document.getElementById("snap");
// Scroll the view to the bottom once initially
container.scrollTop = container.scrollHeight;
container.addEventListener("scroll", (event) => {
const target = event.currentTarget;
const scroll = target.scrollTop;
const maxScroll = target.scrollHeight - target.clientHeight;
const threshold = 50; // px
isScrollBottomedOut = maxScroll - scroll < threshold;
// If the user scrolls up more than the threshold, disable snapping
// If the user scrolls down again, reenable snapping
snap.style.display = isScrollBottomedOut ? "block" : "none";
});
#container {
width: 200px;
height: 500px;
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
-ms-scroll-chaining: none;
overscroll-behavior: contain;
-ms-scroll-snap-type: y proximity;
scroll-snap-type: y proximity;
border: 2px solid black;
}
#snap {
scroll-snap-align: end;
}
<div id="container">
<ol>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ol>
<!-- This is the snapping target, if visible -->
<div id="snap"></div>
</div>
언급URL : https://stackoverflow.com/questions/18614301/keep-overflow-div-scrolled-to-bottom-unless-user-scrolls-up
'programing' 카테고리의 다른 글
| '콜 가능'이란? (0) | 2022.10.14 |
|---|---|
| 도커에서 분리 실행 시 Python 앱이 인쇄되지 않음 (0) | 2022.10.14 |
| JavaScript에서 문자열을 정수로 변환하려면 어떻게 해야 합니까? (0) | 2022.10.14 |
| 텍스트에서 모든 공백 제거 (0) | 2022.10.04 |
| MySQL Select Date Equal to Today(데이터 유형으로 날짜 지정) (0) | 2022.10.04 |
