简体   繁体   English

如何永久地自动滚动到div的底部?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM