当前位置: 首页 > 知识库问答 >
问题:

当外部div大小发生变化时,可滚动div以粘在底部

姜俊民
2023-03-14

这是一个示例聊天应用程序 -

这里的想法是让. Message-容器尽可能多地占据屏幕。在.起动消息容器中,. scroll保存消息列表,如果有比屏幕大小更多的消息,则滚动。

现在,考虑这种情况:

  1. 用户滚动至对话底部
  2. <代码>。文本输入,动态变大

现在,用户不再停留在对话的底部,而是增加了文本输入,他们不再看到底部。

一种解决方法是,如果我们使用react,计算文本输入的高度,如果有任何变化,让。消息-容器知道

componentDidUpdate() {
  window.setTimeout(_ => {
    const newHeight = this.calcHeight();
    if (newHeight !== this._oldHeight) {
      this.props.onResize();
    }
    this._oldHeight = newHeight;
  });
}

但是,这会导致明显的性能问题,像这样传递消息是很可悲的。

有更好的方法吗?我是否可以以这种方式使用css来表达当.文本输入增加时,我想基本上将所有.消息容器向上移动

共有3个答案

钦枫
2023-03-14

请尝试以下小提琴 - https://jsfiddle.net/Hazardous/bypxg25c/。尽管小提琴目前使用jQuery来增大/调整文本区域的大小,但关键在于用于消息容器和输入容器类的flex相关样式 -

.messages-container{
  order:1;
  flex:0.9 1 auto;
  overflow-y:auto;
  display:flex;
  flex-direction:row;
  flex-wrap:nowrap;
  justify-content:flex-start;
  align-items:stretch;
  align-content:stretch;
}

.input-container{
  order:2;
  flex:0.1 0 auto;
}

对于 .消息容器,弹性收缩值设置为 1,对于 .input 容器,弹性收缩值设置为 0。这可确保在重新分配大小时收缩消息容器。

池兴邦
2023-03-14

你只需要一个CSS规则集:

.messages-container, .scroll {transform: scale(1,-1);}

就这样,你完了!

工作原理:首先,它垂直翻转container元素,使顶部变成底部(为我们提供所需的滚动方向),然后翻转content元素,这样消息就不会颠倒。

这种方法适用于所有现代浏览器。不过,它确实有一个奇怪的副作用:当您在消息框中使用鼠标滚轮时,滚动方向会颠倒。这可以通过几行JavaScript来解决,如下所示。

这里有一个演示和一把小提琴可以玩:

//Reverse wheel direction
document.querySelector('.messages-container').addEventListener('wheel', function(e) {
  if(e.deltaY) {
    e.preventDefault();
    e.currentTarget.scrollTop -= e.deltaY;
  }
});

//The rest of the JS just handles the test buttons and is not part of the solution
send = function() {
  var inp = document.querySelector('.text-input');
  document.querySelector('.scroll').insertAdjacentHTML('beforeend', '<p>' + inp.value);
  inp.value = '';
  inp.focus();
}
resize = function() {
  var inp = document.querySelector('.text-input');
  inp.style.height = inp.style.height === '50%' ? null : '50%';
}
html,body {height: 100%;margin: 0;}
.conversation {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.messages-container {
  flex-shrink: 10;
  height: 100%;
  overflow: auto;
}
.messages-container, .scroll {transform: scale(1,-1);}
.text-input {resize: vertical;}
<div class="conversation">
  <div class="messages-container">
    <div class="scroll">
      <p>Message 1<p>Message 2<p>Message 3<p>Message 4<p>Message 5
      <p>Message 6<p>Message 7<p>Message 8<p>Message 9<p>Message 10<p>Message 11<p>Message 12<p>Message 13<p>Message 14<p>Message 15<p>Message 16<p>Message 17<p>Message 18<p>Message 19<p>Message 20
    </div>
  </div>
  <textarea class="text-input" autofocus>Your message</textarea>
  <div>
    <button id="send" onclick="send();">Send input</button>
    <button id="resize" onclick="resize();">Resize input box</button>
  </div>
</div>
云项禹
2023-03-14

第二:修改这个答案

你在这里的朋友是flexdirection:column reverse可以满足您的所有要求,同时将消息容器底部的消息对齐,就像Skype和许多其他聊天应用程序一样。

.chat-window{
  display:flex;
  flex-direction:column;
  height:100%;
}
.chat-messages{
  flex: 1;
  height:100%;
  overflow: auto;
  display: flex;
  flex-direction: column-reverse;
}

.chat-input { border-top: 1px solid #999; padding: 20px 5px }
.chat-input-text { width: 60%; min-height: 40px; max-width: 60%; }

flex方向的缺点是:列反转是IE/Edge/Fefox中的一个bug,滚动条不显示,您可以在此处阅读更多信息:Firefox/IE中的Flexbox列反转和溢出

好处是您在手机/平板电脑上有〜90%的浏览器支持,对台式机的支持率为〜65%,并且随着错误得到修复,...并且有一个解决方法。

// scroll to bottom
function updateScroll(el){
  el.scrollTop = el.scrollHeight;
}
// only shift-up if at bottom
function scrollAtBottom(el){
  return (el.scrollTop + 5 >= (el.scrollHeight - el.offsetHeight));
}

在下面的代码片段中,我添加了上面的2个函数,以使IE / Edge / Firefox以与弹性方向相同的方式运行:列反转;

function addContent () {
  var msgdiv = document.getElementById('messages');
  var msgtxt = document.getElementById('inputs');
  var atbottom = scrollAtBottom(msgdiv);

  if (msgtxt.value.length > 0) {
    msgdiv.innerHTML += msgtxt.value + '<br/>';
    msgtxt.value = "";
  } else {
    msgdiv.innerHTML += 'Long long content ' + (tempCounter++) + '!<br/>';
  }
  
  /* if at bottom and is IE/Edge/Firefox */
  if (atbottom && (!isWebkit || isEdge)) {
    updateScroll(msgdiv);
  }
}

function resizeInput () {
  var msgdiv = document.getElementById('messages');
  var msgtxt = document.getElementById('inputs');
  var atbottom = scrollAtBottom(msgdiv);

  if (msgtxt.style.height == '120px') {
    msgtxt.style.height = 'auto';
  } else {
    msgtxt.style.height = '120px';
  }
  
  /* if at bottom and is IE/Edge/Firefox */
  if (atbottom && (!isWebkit || isEdge)) {
    updateScroll(msgdiv);
  }
}


/* fix for IE/Edge/Firefox */
var isWebkit = ('WebkitAppearance' in document.documentElement.style);
var isEdge = ('-ms-accelerator' in document.documentElement.style);
var tempCounter = 6;

function updateScroll(el){
  el.scrollTop = el.scrollHeight;
}
function scrollAtBottom(el){
  return (el.scrollTop + 5 >= (el.scrollHeight - el.offsetHeight));
}
html, body { height:100%; margin:0; padding:0; }

.chat-window{
  display:flex;
  flex-direction:column;
  height:100%;
}
.chat-messages{
  flex: 1;
  height:100%;
  overflow: auto;
  display: flex;
  flex-direction: column-reverse;
}

.chat-input { border-top: 1px solid #999; padding: 20px 5px }
.chat-input-text { width: 60%; min-height: 40px; max-width: 60%; }


/* temp. buttons for demo */
button { width: 12%; height: 44px; margin-left: 5%; vertical-align: top; }

/* begin - fix for hidden scrollbar in IE/Edge/Firefox */
.chat-messages-text{ overflow: auto; }
@media screen and (-webkit-min-device-pixel-ratio:0) {
  .chat-messages-text{ overflow: visible; }
  /*  reset Edge as it identifies itself as webkit  */
  @supports (-ms-accelerator:true) { .chat-messages-text{ overflow: auto; } }
}
/* hide resize FF */
@-moz-document url-prefix() { .chat-input-text { resize: none } }
/* end - fix for hidden scrollbar in IE/Edge/Firefox */
<div class="chat-window">
  <div class="chat-messages">
    <div class="chat-messages-text" id="messages">
      Long long content 1!<br/>
      Long long content 2!<br/>
      Long long content 3!<br/>
      Long long content 4!<br/>
      Long long content 5!<br/>
    </div>
  </div>
  <div class="chat-input">
    <textarea class="chat-input-text" placeholder="Type your message here..." id="inputs"></textarea>
    <button onclick="addContent();">Add msg</button>
    <button onclick="resizeInput();">Resize input</button>
  </div>
</div>
 类似资料:
  • 问题内容: 这是一个聊天应用示例-> 这里的想法是尽可能多地占用屏幕。在中,保存消息列表,如果还有更多消息,则滚动屏幕尺寸。 现在,考虑这种情况: 用户滚动到对话的底部 的,动态地变大 现在,文本输入增加了,而不再是用户滚动到对话的底部,而是不再看到底部。 解决该问题的一种方法,如果我们使用react,请计算文本输入的高度,如果有任何变化,请让.messages-container知道 但是,这会

  • 问题内容: 我正在使用Ajax请求创建聊天,并且试图使消息div滚动到底部没有太多运气。 我将所有内容包装在这个div中: 有没有一种方法可以使用JS将其默认滚动到底部? 有没有一种方法可以在ajax请求后将其滚动到底部? 问题答案: 这是我在网站上使用的内容:

  • 问题内容: 我正在使用Rails中的Ajax请求创建聊天,并且试图使div滚动到底部没有太多运气。 我将所有内容包装在这个div中: 有没有一种方法可以使用JS将其默认滚动到底部? 有没有办法在ajax请求之后将其滚动到底部? 问题答案: 这是我在网站上使用的内容:

  • 问题内容: 我的页面上有一个div: 如何使div滚动到div的底部?不是页面,只有DIV。 问题答案: 此处的其他解决方案实际上不适用于内容很多的div -它“最大化”向下滚动到div的高度(而不是div 内容 的高度)。因此,它们将起作用,除非您在其内容中具有div高度的两倍以上。 这是正确的版本: 或jQuery 1.6+版本: 或动画:

  • 本文向大家介绍jquery拖动改变div大小,包括了jquery拖动改变div大小的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了jquery拖动改变div大小的具体代码,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 目的 我有一个固定高度和宽度的主DIV,因为我想让许多小型DIV自由浮动。我的小型DIV超出了主DIV的容量。然后,默认情况下,似乎是小DIV 在主DIV之外消失 了 。我希望它们反而消失在右边。 我想触发水平滚动条,但不触发垂直滚动条。 背景 我按照 如果我的主DIV中只有文本或图像,它会非常完美。 题 但是,当主DIV仅包含小型DIV时,该怎么办? 问题答案: 像这样,将较小的di