gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 03:12:42 26 4
gpt4 key购买 nike

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

这里的想法是让 .messages-container 尽可能多地占据屏幕。在 .messages-container 中,.scroll 包含消息列表,如果消息多于屏幕大小,则滚动。

现在,考虑这种情况:

  1. 用户滚动到对话的底部
  2. .text-input,动态变大

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

修复它的一种方法,如果我们使用 React,计算文本输入的高度,如果有任何变化,让 .messages-container 知道

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

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

有没有更好的方法?我可以这样使用 css 来表达当 .text-input-increases 时,我想基本上 shift up all of .messages-container

最佳答案

第 2 次修订此答案

你的 friend 是 flex-direction: 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-direction: column-reverse; 的缺点是 IE/Edge/Firefox 中的错误,滚动条不显示,您可以在此处阅读更多信息:Flexbox column-reverse and overflow in Firefox/IE

好处是您在移动设备/平板电脑上有约 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 的行为方式与 flex-direction: column-reverse; 相同。

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>


旁注 1:检测方法尚未经过全面测试,但它应该适用于较新的浏览器。

旁注 2:为聊天输入附加一个调整大小的事件处理程序可能比调用 updateScroll 函数更有效。

注意:感谢 HaZardouS 重用他的 html 结构

关于javascript - 可滚动的 div 粘在底部,当外部 div 的大小发生变化时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34213227/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com