它可以Flexbox吗?聊天窗口在底部输入,聊天向上滚动 [英] Can it flexbox? Chat window with input at the bottom, chats scrolling up

查看:91
本文介绍了它可以Flexbox吗?聊天窗口在底部输入,聊天向上滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看起来好像应该可以使用flexbox,但我无法弄清楚。



http://codepen.io/MichaelJCole/pen/NGBVGe



目标:


  1. textarea(用于输入消息)始终停留在底部。
  2. 聊天开始于底部,然后
  3. 如果您使用Google环聊,就像那个消息应用程序一样。

以下是标记:

 < div id =chatBar> 
< div id =chatList>
< div class =chat mine> hello world< / div>
< div class =chat theirs> hello moon< / div>
< / div>
< input id =chatBarInputclass =form-controltype =textarea>
< / div>

以下是CSS:

  html,body {height:100%; } 
#chatBar {
height:100%;
display:flex;
flex-flow:列nowrap;
justify-content:flex-end;
溢出:无;
}

#chatList {
flex:0 1 auto;
display:flex;
flex-flow:列nowrap;
justify-content:flex-end;
overflow-y:scroll;
}

#chatBarInput {
flex:1 0 auto;
}

.chat {
flex:none;
align-self:flex-start;
background-color:lightgreen;
}

.chat.mine {
align-self:flex-end;
background-color:pink;
}

我无法获得 #chatBar 到挤压 #chatList ,而不设置高度。这是我试图通过使用flexbox避免的: - /



对不起,我是一个后端编码器。试了一堆东西,然后削减CodePen。

好像我应该能够告诉内部的柔性滚动条,而不用单独的滚动。我必须使用position:absolute?

解决方案


我无法将#chatBar设置为挤压#chatList没有设置高度。
这就是我试图通过使用flexbox避免的情况


您有 flex-basis 为所有元素设置为 auto 。如果没有明确的高度,Flex模型将自动尝试通过缩小或扩展元素来容纳可用空间内的所有内容。这就是为什么你无法获得 #chatList 按预期工作。 div 本身以及单个聊天内容都可以在可用空间内展开或缩小。

你应该做什么是开始简单:

  #chatBar {
height:100%;溢出:隐藏;
display:flex; flex-flow:column;
}
#chatList {
/ *根据需要从flex的基础高度增加或减少20%* /
flex:1 1 20%;
display:flex; flex-direction:column;
溢出:auto;
}

/ *不会随着80%的弹性基础高度而增长或缩小* /
#chatBarInput {flex:0 0 80%; }

你将能够看到它的工作。那么你可以从这里进一步。

您修改的codepen: http:// codepen .io / Abhitalks / pen / ZbjNvQ /





p>


  1. textarea(用于输入消息)始终停留在底部。
  2. 聊天开始于底部,然后根据需要向上滚动。



$ b $如果您使用Google环聊 b

诀窍是使用 flex-direction:column-reverse ,并将新消息添加到容器中,而不是附加这些消息。 >

我回答了我的一个旧的答案,并将布局更改为flex-model进行演示。您可以仔细阅读代码,看看它是如何完成的。



Demo小提琴: http://jsfiddle.net/abhitalks/khj4903t/

演示片段:



  var btn = document.getElementById('btn'),inp = document.getElementById('inp'),chats = document.getElementById ('chatWindow');函数postMsg();函数(){var msg = inp.value,bubble = document.createElement('div'),p = document.createElement('p');如果(msg.trim()。length <= 0){return; } bubble.classList.add('bubble'); bubble.classList.add(右); p.textContent = msg; bubble.appendChild(P); inp.value =''; chats.insertBefore(bubble,chats.firstChild);}  

* {box-sizing:border-box;保证金:0;填充:0; } html,body {height:100%;溢出:隐藏; } .wrap {margin:8px;身高:90%宽度:50%;显示:flex; flex-direction:column;}。container {flex:1 1 90%;显示:flex; flex-direction:column; background-color:#eee; border:1px solid #ccc; overflow:auto;}。form {flex:0 0 32px;显示:flex; border:1px solid #ddd; } .form>输入[type = text] {flex:1 1 auto; border:1px solid #eee; } .form>输入[type = button] {flex:0 0 20%; border:1px solid #eee; } .bubble {flex:1 1 auto;明确:两者; } / *清除父类的浮点数* /。bubble p {border-radius:5px; padding:8px; margin:8px 12px;最大宽度:80%; / *这会使它不超过80%,然后换行* / position:relative;过渡:背景色0.5s; } .left p {background-color:#ccc;向左飘浮; } / *左边浮动* /。右边p {background-color:#33c;颜色:#fff; float:right; } / *正确的浮动* // *下面的类只用于箭头,不相关* /。位置:绝对;宽度:0;身高:0; left:-8px;顶部:8px; border-top:4px透明; border-right:8px solid #ccc; border-bottom:4px solid transparent;}。right p :: after {content:'';位置:绝对;宽度:0;身高:0;正确:-8px;底部:8px; border-top:4px透明; border-left:8px solid#33c; border-bottom:4px solid transparent;}

< div类= 包裹 > < div id =chatWindowclass =container> < div class =bubble left>< p> msg< / p>< / div> < div class =bubble left>< p>长信息< / p>< / div> < div class =bubble right>< p>超长邮件可​​以在百分之八十的百分比< / p>< / div> < div class =bubble left>< p> lorem ipsum< / p>< / div> < div class =bubble right>< p>很长的讯息< / p>< / div> < div class =bubble right>< p>多一个讯息< / p>< / div> < div class =bubble left>< p> lorem ipsum< / p>< / div> < div class =bubble right>< p>另一个讯息< / p>< / div> < div class =bubble left>< p> lorem ipsum< / p>< / div> < div class =bubble right>< p>另一个讯息< / p>< / div> < div class =bubble left>< p> lorem ipsum< / p>< / div> < / DIV> < div id =inputWindowclass =form> < input id =inptype =text/> < input id =btntype =buttonvalue =Send/> < / div>< / div>

Seems like it should be possible with flexbox, but I can't figure it out.

http://codepen.io/MichaelJCole/pen/NGBVGe

Goals:

  1. textarea (for typeing in messages) stays at the bottom the whole time.
  2. chats start at the bottom, then scroll up as needed.
  3. If you use the "Google Hangouts", like the message app in that.

Here's the markup:

 <div id="chatBar">
    <div id="chatList">
      <div class="chat mine">hello world</div>
      <div class="chat theirs">hello moon</div>
    </div>
    <input id="chatBarInput" class="form-control" type="textarea">
  </div>

And here's the CSS:

html, body { height: 100%; }
#chatBar {
  height: 100%;
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-end;
  overflow: none;
}

#chatList {
  flex: 0 1 auto;
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-end;
  overflow-y: scroll;
}

#chatBarInput {
  flex: 1 0 auto;
}

.chat {
  flex: none;
  align-self: flex-start;
  background-color: lightgreen;
}

.chat.mine {
  align-self: flex-end;
  background-color: pink;
}

I can't get #chatBar to "squeeze" #chatList without setting a height. Which is what I was trying to avoid by using flexbox :-/

Sorry, I'm a backend coder. Tried a bunch of stuff, then pared it down for the CodePen.

Seems like I should be able to tell the inner flexbox to scroll, while leaving the outer alone. Do I have to use position:absolute?

解决方案

I can't get #chatBar to "squeeze" #chatList without setting a height. Which is what I was trying to avoid by using flexbox

You had the flex-basis set to auto for all elements. Without explicit height, the flex model will automatically try to accommodate everything inside the available space by shrinking or expanding the elements. This is why you are unable to get the #chatList to work as intended. The div itself as well as the individual chats all expand or shrink within the available space.

What you should do is to start simple:

#chatBar {
    height: 100%; overflow: hidden;
    display: flex; flex-flow: column;
}
#chatList {
    /* grow or shrink as required from flex-basis height of 20% */
    flex: 1 1 20%; 
    display: flex; flex-direction: column; 
    overflow: auto;
} 

/* do not grow or shrink with a flex-basis height of 80% */
#chatBarInput { flex: 0 0 80%; }

And you will be able to see it working. You could then take it further from here.

Your modified codepen: http://codepen.io/Abhitalks/pen/ZbjNvQ/


Goals:

  1. textarea (for typeing in messages) stays at the bottom the whole time.
  2. chats start at the bottom, then scroll up as needed.
  3. If you use the "Google Hangouts", like the message app in that.

The trick would be to use flex-direction: column-reverse and prepend the new messages to the container instead of appending those.

I took an old answer of mine and changed the layout to flex-model for a demo of this purpose. You can peruse the code to see how it's done.

Demo Fiddle: http://jsfiddle.net/abhitalks/khj4903t/

Demo Snippet:

var btn 	= document.getElementById('btn'), 
    inp 	= document.getElementById('inp'), 
    chats	= document.getElementById('chatWindow')
;
btn.addEventListener('click', postMsg);

inp.addEventListener('keyup', function(e) {
	if (e.keyCode == 13) { postMsg(); }
});

function postMsg() {
	var msg 	= inp.value,
        bubble 	= document.createElement('div'),
        p 		= document.createElement('p');
    if (msg.trim().length <= 0) { return; }
    bubble.classList.add('bubble');
    bubble.classList.add('right');
    p.textContent = msg;
    bubble.appendChild(p);
    inp.value = '';
    chats.insertBefore(bubble, chats.firstChild);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
.wrap { 
    margin: 8px; height: 90%; width: 50%; 
    display: flex; flex-direction: column;
}
.container {
    flex: 1 1 90%; display: flex; flex-direction: column; 
    background-color: #eee; border: 1px solid #ccc; overflow: auto;
}
.form { flex: 0 0 32px; display: flex; border: 1px solid #ddd; }
.form > input[type=text] { flex: 1 1 auto; border: 1px solid #eee; }
.form > input[type=button] { flex: 0 0 20%; border: 1px solid #eee; }
.bubble { flex: 1 1 auto; clear: both; } /* clear the floats here on parent */
.bubble p {
    border-radius: 5px;
    padding: 8px; margin: 8px 12px;
    max-width: 80%;  /* this will make it not exceed 80% and then wrap */
    position: relative; transition: background-color 0.5s; 
}
.left p { background-color: #ccc; float: left; } /* floated left */
.right p { background-color: #33c; color: #fff; float: right; } /* floated right */
/* classes below are only for arrows, not relevant */
.left p::before {
    content: ''; position: absolute;
    width: 0; height: 0; left: -8px; top: 8px;
    border-top: 4px solid transparent;
    border-right: 8px solid #ccc;
    border-bottom: 4px solid transparent;
}
.right p::after {
    content: ''; position: absolute;
    width: 0; height: 0; right: -8px; bottom: 8px;
    border-top: 4px solid transparent;
    border-left: 8px solid #33c;
    border-bottom: 4px solid transparent;
}

<div class="wrap">
    <div id="chatWindow" class="container">
        <div class="bubble left"><p>msg</p></div>
        <div class="bubble left"><p>long message</p></div>
        <div class="bubble right"><p>ultra long message which can wrap at eighty percent </p></div>
        <div class="bubble left"><p>lorem ipsum</p></div>
        <div class="bubble right"><p>very long message</p></div>    
        <div class="bubble right"><p>one more message</p></div>    
        <div class="bubble left"><p>lorem ipsum</p></div>
        <div class="bubble right"><p>another message</p></div>    
        <div class="bubble left"><p>lorem ipsum</p></div>
        <div class="bubble right"><p>yet another message</p></div>    
        <div class="bubble left"><p>lorem ipsum</p></div>
    </div>
    <div id="inputWindow" class="form">
        <input id="inp" type="text" />
        <input id="btn" type="button" value="Send" />
    </div>
</div>

这篇关于它可以Flexbox吗?聊天窗口在底部输入,聊天向上滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆