【问题标题】:How to auto-scroll to the bottom of a div perpetually?如何永久自动滚动到 div 的底部?
【发布时间】:2016-12-09 01:55:41
【问题描述】:

我有一个带有滚动功能的<div>。通过 JavaScript,我将元素添加到 <div>element.scrollTop = element.scrollHeight。效果很好,除非每次将元素添加到<div> 时我都必须这样做。有没有办法自动滚动(不使用setInterval 并反复滚动)并保持<div> 的滚动条固定在底部?

我的<div>

<div class="messages" style="height: 7em; overflow: scroll">
  <div>Anonymous: Hello</div>
  <div>John: Hi</div>
</div>

内容更改时是否有&lt;div&gt; 事件?

更新:在添加&lt;div&gt;之后,我无法轻松访问 JavaScript 代码。这就是为什么我喜欢添加一个事件监听器或其他一些机制来保持滚动条固定在底部。

【问题讨论】:

  • 你为什么使用 setInterval?如果有新事件发生,您应该滚动。
  • 更具体地说:只有在添加新元素时才滚动到底部并且你在它之前已经在底部,否则你的用户会讨厌你。
  • 我认为在将元素添加到&lt;div&gt; 之后执行element.scrollTop = element.scrollHeight 没有任何问题。
  • 您可能想要 MutationObserver developer.mozilla.org/en/docs/Web/API/MutationObserver ,但是,如果您自己的代码完成了 DOM 操作,为什么不直接调用滚动函数呢?
  • 你至少可以发布你的js代码吗? @at

标签: javascript css html dom-events


【解决方案1】:

创建一个变量var index = 0。将tabIndex 属性添加到动态创建的元素中,将index 设置为.valuetabIndex 属性。将元素附加到父元素后,在动态创建的元素上调用.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>

plnkrhttps://plnkr.co/edit/34QUtpGNVfho2fmYIlUI?p=preview

【讨论】:

  • 不错的独特方法。我从没想过 div 可以成为焦点。 (+1)
  • 好主意!不幸的是,它不适用于我的情况,因为人们需要在消息进来时打字……类似于聊天应用程序。不能在打字时不断转移注意力:)
【解决方案2】:

你可以覆盖目标元素的addChild方法或者你可以使用MutationOvserver来观察DOM。

给定 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>

覆盖方法方法:

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 方法:

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 = '';
    }
  });

});

注意:不确定element.appendChild 方法是否用于添加消息,例如可以在Element.prototype.appendChild.call(msgs, childNode); 行或insertBefore 中附加一个孩子。所以第二种方法更像是一种“包罗万象”的方法。

【讨论】:

  • MutationObserver 正是我所希望的!感谢@Quasimodo 的克隆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-13
  • 2010-09-21
相关资源
最近更新 更多