[英]How to auto-scroll to the bottom of a div perpetually?
I have a <div>
with scrolling. 我有一个滚动的
<div>
。 Through JavaScript I add elements to the <div>
with element.scrollTop = element.scrollHeight
. 通过JavaScript,我使用
element.scrollTop = element.scrollHeight
向<div>
添加元素。 Works great except I have to do that every time an element is added to the <div>
. 除了每次将一个元素添加到
<div>
时我都必须这样做,所以效果很好。 Is there a way to auto-scroll (without using setInterval
and repeatedly scrolling over and over) and keep the <div>
's scrollbar pegged to the bottom? 有没有办法自动滚动(不使用
setInterval
并反复滚动)并将<div>
的滚动条固定在底部?
My <div>
: 我的
<div>
:
<div class="messages" style="height: 7em; overflow: scroll">
<div>Anonymous: Hello</div>
<div>John: Hi</div>
</div>
Is there a <div>
event for when the content changes? 内容发生变化时是否有
<div>
事件?
UPDATE : I don't have easy access to JavaScript code after the <div>
is added. 更新 :添加
<div>
后 ,我无法轻松访问JavaScript代码。 That's why I'd love to add an event listener or some other mechanism to keep the scroll bar pegged to the bottom. 这就是为什么我喜欢添加事件监听器或其他一些机制来保持滚动条与底部挂钩。
Create a variable var index = 0
. 创建变量
var index = 0
。 Add tabIndex
attribute to the dynamically created element with index
set as .value
of tabIndex
attribute. 将
tabIndex
属性添加到动态创建的元素中, index
设置为tabIndex
属性的.value
。 Call .focus()
on dynamically created element after appending element to parent element. 将元素追加到父元素后,在动态创建的元素上调用
.focus()
。
var index = 0;
var div = document.createElement("div");
div.setAttribute("tabIndex", index);
document.querySelector(".messages").appendChild(div);
div.focus();
++index;
window.onload = function() { var messages = document.querySelector(".messages"); var index = 0; setInterval(function() { var div = document.createElement("div"); div.setAttribute("tabIndex", index); div.innerHTML = "abc"; messages.appendChild(div); div.focus(); ++index; }, 2000) }
<div class="messages" style="height: 7em; overflow: scroll"> <div>Anonymous: Hello</div> <div>John: Hi</div> </div>
plnkr https://plnkr.co/edit/34QUtpGNVfho2fmYIlUI?p=preview plnkr https://plnkr.co/edit/34QUtpGNVfho2fmYIlUI?p=preview
You could overwrite the addChild
method of the target element or you can use the MutationOvserver
to observe the DOM. 你可以覆盖
addChild
目标元素的方法,也可以使用MutationOvserver
观察DOM。
given HTML: 给定HTML:
<div id="messages-out" class="messages" style="height: 7em; overflow: scroll">
<div>Anonymous: Hello</div>
<div>John: Hi</div>
</div>
<input id="txtMessage" type="text" autofocus>
overwritten method approach: 覆盖方法方法:
document.addEventListener('DOMContentLoaded', function(ev)
{
var msgs = document.getElementById('messages-out');
msgs.appendChild = function(childNode)
{
Element.prototype.appendChild.call(msgs, childNode);
msgs.scrollTop = msgs.scrollHeight;
}
document.getElementById('txtMessage').addEventListener('keypress', function(ev)
{
if(13 === ev.which)
{
var div = document.createElement('div');
div.innerHTML = '<em>nick: </em>' + ev.target.value;
msgs.appendChild(div);
ev.target.value = '';
}
});
})
MutationObserver approach: MutationObserver方法:
document.addEventListener('DOMContentLoaded', function(ev) {
var
msgs = document.getElementById('messages-out'),
observer = new MutationObserver(function (mutations)
{
var added = false;
mutations.forEach(function (mutation) {
if ('childList' === mutation.type && 0 < mutation.addedNodes.length)
added = true;
});
if (added)
msgs.scrollTop = msgs.scrollHeight;
})
;
observer.observe(msgs, {childList: true});
document.getElementById('txtMessage').addEventListener('keypress', function(ev)
{
if(13 === ev.which)
{
var div = document.createElement('div');
div.innerHTML = '<em>nick: </em>' + ev.target.value;
msgs.appendChild(div);
ev.target.value = '';
}
});
});
Note: It is not sure that the element.appendChild
method is used to add a message, eg a child could be appended as in in the line Element.prototype.appendChild.call(msgs, childNode);
注意:不确定
element.appendChild
方法是否用于添加消息,例如,可以在element.appendChild
Element.prototype.appendChild.call(msgs, childNode);
添加子element.appendChild
Element.prototype.appendChild.call(msgs, childNode);
or by insertBefore
. 或者通过
insertBefore
。 So the second approach is more the "catch all" one. 所以第二种方法更像是“抓住所有”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.