我有一个div,只有300像素大,我希望它在页面加载时滚动到内容的底部。这个div有动态添加的内容,需要一直向下滚动。现在如果用户决定向上滚动,我不希望它跳回底部,直到用户再次向下滚动
是否有可能有一个div,将保持滚动到底部,除非用户向上滚动,当用户滚动回底部时,它需要保持自己在底部,即使添加了新的动态内容。我该怎么做呢。
我有一个div,只有300像素大,我希望它在页面加载时滚动到内容的底部。这个div有动态添加的内容,需要一直向下滚动。现在如果用户决定向上滚动,我不希望它跳回底部,直到用户再次向下滚动
是否有可能有一个div,将保持滚动到底部,除非用户向上滚动,当用户滚动回底部时,它需要保持自己在底部,即使添加了新的动态内容。我该怎么做呢。
当前回答
你可以用这样的东西,
var element = document.getElementById("yourDivID");
window.scrollTo(0,element.offsetHeight);
其他回答
Jim Hall的答案更可取,因为当你向上滚动时,它确实不会滚动到底部,它也是纯CSS。
然而,非常不幸的是,这不是一个稳定的解决方案:在chrome(可能是由于1像素的问题由dotnetCarpenter上面描述),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是直线的高度。
因此,当用户向上滚动半行时(如果可能的话?),Javascript将忽略它并滚动到底部。但我想这是可以忽略的。而且,它修复了Chrome 1px的东西。
我设法把它修好了。诀窍是计算:(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 });
}
$('#div1').scrollTop($('#div1')[0].scrollHeight);
Or animated:
$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);
我不能让前两个答案工作,其他答案都对我没有帮助。所以我从Reddit r/forhire和Upwork上给了三个人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);
});
预览网站兄弟的解决方案
投资组合
莱尔梅克斯/斯维亚托斯拉夫·丘马科夫的解决方案
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的解决方案
投资组合
我刚刚实现了这个,也许你可以用我的方法。
假设我们有以下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 gives you the height of the element, including any non visible area due to overflow. clientHeight gives 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. scrollTop gives 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.
然后,只需将元素的scrollTop设置为底部即可。
if(isScrolledToBottom)
out.scrollTop = out.scrollHeight - out.clientHeight;
我已经为你做了一个小提琴的概念:http://jsfiddle.net/dotnetCarpenter/KpM5j/
编辑: 增加了代码片段以澄清当isScrolledToBottom为真时。
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>