jQuery 除非用户向上滚动,否则将溢出 div 滚动到底部
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18614301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Keep overflow div scrolled to bottom unless user scrolls up
提问by Robert E. McIntosh
I have a div that is only 300 pixels big and I want it to when the page loads scroll to the bottom of the content. This div has content dynamically added to it and needs to stay scrolled all the way down. Now if the user decides to scroll up I don't want it to jump back to the bottom until the user scrolls all the way down again
我有一个只有 300 像素大的 div,我希望它在页面加载时滚动到内容的底部。这个 div 有动态添加的内容,需要一直向下滚动。现在,如果用户决定向上滚动,我不希望它跳回底部,直到用户再次向下滚动
Is it possible to have a div that will stay scrolled to the bottom unless the user scrolls up and when the user scrolls back to the bottom it needs to keep itself at the bottom even when new dynamic content is added. How would I go bout creating this.
是否有可能让 div 保持滚动到底部,除非用户向上滚动,并且当用户滚动回底部时,即使添加了新的动态内容,它也需要将自己保持在底部。我将如何创建这个。
采纳答案by Mr.Manhattan
This might help you:
这可能会帮助您:
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
[EDIT], to match the comment...
[编辑],匹配评论...
function updateScroll(){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
whenever content is added, call the function updateScroll(), or set a timer:
每当添加内容时,调用函数 updateScroll(),或设置一个计时器:
//once a second
setInterval(updateScroll,1000);
if you want to update ONLY if the user didn't move:
如果您只想在用户未移动时更新:
var scrolled = false;
function updateScroll(){
if(!scrolled){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
}
$("#yourDivID").on('scroll', function(){
scrolled=true;
});
回答by Jim Hall
I was able to get this working with CSS only.
我只能使用 CSS 来实现它。
The trick is to use display: flex;
and flex-direction: column-reverse;
诀窍是使用display: flex;
和flex-direction: column-reverse;
The browser treats the bottom like its the top. Assuming the browsers you're targeting support flex-box
, the only caveat is that the markup has to be in reverse order.
浏览器将底部视为顶部。假设您的目标浏览器是 support flex-box
,唯一需要注意的是标记必须以相反的顺序排列。
Here is a working example. https://codepen.io/jimbol/pen/YVJzBg
这是一个工作示例。https://codepen.io/jimbol/pen/YVJzBg
回答by dotnetCarpenter
I just implemented this and perhaps you can use my approach.
我刚刚实现了这个,也许你可以使用我的方法。
Say we have the following HTML:
假设我们有以下 HTML:
<div id="out" style="overflow:auto"></div>
Then we can check if it scrolled to the bottom with:
然后我们可以检查它是否滚动到底部:
var out = document.getElementById("out");
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
scrollHeightgives you the height of the element, including any non visible area due to overflow. clientHeightgives you the CSS height or said in another way, the actual height of the element. Both methods returns the height without margin
, so you needn't worry about that. scrollTopgives you the position of the vertical scroll. 0 is top and max is the scrollHeight of the element minus the element height itself. When using the scrollbar it can be difficult (it was in Chrome for me) to get the scrollbar all the way down to the bottom. so I threw in a 1px inaccuracy. So isScrolledToBottom
will be true even if the scrollbar is 1px from the bottom. You can set this to whatever feels right to you.
scrollHeight为您提供元素的高度,包括由于溢出而导致的任何不可见区域。clientHeight为您提供 CSS 高度或换句话说,元素的实际高度。这两种方法都返回没有 的高度margin
,所以你不必担心。scrollTop为您提供垂直滚动的位置。0 是顶部,max 是元素的滚动高度减去元素本身的高度。使用滚动条时,将滚动条一直拖到底部可能很困难(对我来说是在 Chrome 中)。所以我抛出了 1px 的误差。因此,isScrolledToBottom
将真实的,即使滚动条从底部1px的。您可以将其设置为您认为合适的任何内容。
Then it's simply a matter of setting the scrollTop of the element to the bottom.
那么只需将元素的 scrollTop 设置为底部即可。
if(isScrolledToBottom)
out.scrollTop = out.scrollHeight - out.clientHeight;
I have made a fiddle for you to show the concept: http://jsfiddle.net/dotnetCarpenter/KpM5j/
我为你做了一个小提琴来展示这个概念:http: //jsfiddle.net/dotnetCarpenter/KpM5j/
EDIT:
Added code snippet to clarify when isScrolledToBottom
is true
.
编辑:添加了代码片段以阐明何时isScrolledToBottom
是true
。
Stick scrollbar to bottom
将滚动条粘到底部
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>
回答by Alvaro
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);
Live demo: http://jsfiddle.net/KGfG2/
现场演示:http: //jsfiddle.net/KGfG2/
回答by Sasidharan
$('#div1').scrollTop($('#div1')[0].scrollHeight);
Or animated:
$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);
回答by wener
In 2020, you can use css snap, but before Chrome 81 the layout change will not trigger re-snap, a pure css chat uiworks on Chrome 81, also you can check Can I use CSS snap.
在 2020 年,您可以使用css snap,但在 Chrome 81 之前,布局更改不会触发 re-snap,纯 css chat ui可在 Chrome 81 上运行,您也可以查看Can I use CSS snap。
This demo will snap the last element if visible, scroll to bottom to see the effect.
如果可见,此演示将捕捉最后一个元素,滚动到底部以查看效果。
.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>
回答by yisheng wu
.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
to see the effect. (PS: IfRun code snippet
is not working, try this: https://jsfiddle.net/Yeshen/xm2yLksu/3/)How it work:
Run code snippet
看看效果。(PS:如果Run code snippet
不工作,试试这个:https: //jsfiddle.net/Yeshen/xm2yLksu/3/)它是如何工作的:
Default overflow is scroll from top to bottom.
默认溢出是从上到下滚动。
transform: rotate(180deg)
can make it scroll or load dynamic block from bottom to top.
transform: rotate(180deg)
可以让它从下到上滚动或加载动态块。
- Original idea:
- 创见:
回答by Krishnadas PC
$('#yourDivID').animate({ scrollTop: $(document).height() }, "slow");
return false;
This will calculate the ScrollTop Position from the height of #yourDivID
using the $(document).height()
property so that even if dynamic contents are added to the div the scroller will always be at the bottom position. Hope this helps. But it also has a small bug even if we scroll up and leaves the mouse pointer from the scroller it will automatically come to the bottom position. If somebody could correct that also it will be nice.
这将从#yourDivID
使用该$(document).height()
属性的高度计算 ScrollTop 位置,以便即使将动态内容添加到 div 滚动条也将始终位于底部位置。希望这可以帮助。但是它也有一个小错误,即使我们向上滚动并将鼠标指针从滚动条上离开,它也会自动到达底部位置。如果有人可以纠正它也会很好。
回答by KingOfDaNorth
//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;
Here is my version based on dotnetCarpenter's answer. My approach is a pure jQuery and I named the variables to make things a bit clearer.. What is happening is if the content height is greater then the container we scroll the extra distance down to achieve the desired result.
这是我基于 dotnetCarpenter 回答的版本。我的方法是一个纯 jQuery,我命名变量以使事情更清楚。发生的事情是如果内容高度大于容器,我们向下滚动额外的距离以实现所需的结果。
Works in IE and chrome..
适用于 IE 和 chrome..
回答by phil294
Jim Hall's answer is preferrable because while it indeed does not scroll to the bottom when you're scrolled up, it is also pure CSS.
Jim Hall 的回答是可取的,因为虽然向上滚动时它确实不会滚动到底部,但它也是纯 CSS。
Very much unfortunately however, this is not a stable solution: In chrome (possibly due to the 1-px-issue described by dotnetCarpenter above), scrollTop
behaves inaccurately by 1 pixel, even without user interaction (upon element add). You can set scrollTop = scrollHeight - clientHeight
, but that will keep the div in position when another element is added, aka the "keep itself at bottom" feature is not working anymore.
然而,非常不幸的是,这不是一个稳定的解决方案:在 chrome 中(可能是由于上面 dotnetCarpenter 描述的 1-px 问题)scrollTop
,即使没有用户交互(添加元素时),其行为也会不准确 1 像素。您可以设置scrollTop = scrollHeight - clientHeight
,但是这将在添加另一个元素时保持 div 的位置,也就是“保持自己在底部”功能不再起作用。
So, in short, adding a small amount of Javascript (sigh) will fix this and fulfill all requirements:
因此,简而言之,添加少量 Javascript(叹气)将解决此问题并满足所有要求:
Something like https://codepen.io/anon/pen/pdrLEZthis (example by Coo), and after adding an element to the list, also the following:
类似于https://codepen.io/anon/pen/pdrLEZ这个(Coo 的例子),在向列表中添加一个元素后,还有以下内容:
container = ...
if(container.scrollHeight - container.clientHeight - container.scrollTop <= 29) {
container.scrollTop = container.scrollHeight - container.clientHeight;
}
where 29 is the height of one line.
其中 29 是一行的高度。
So, when the user scrolls up half a line (if that is even possible?), the Javascript will ignore it and scroll to the bottom. But I guess this is neglectible. And, it fixes the Chrome 1 px thingy.
因此,当用户向上滚动半行时(如果这甚至可能?),Javascript 将忽略它并滚动到底部。但我想这是可以忽略的。而且,它修复了 Chrome 1 px 的东西。