聊天应用程序的从下到上的布局设计

Posted

技术标签:

【中文标题】聊天应用程序的从下到上的布局设计【英文标题】:Bottom to top layout desing for chat application 【发布时间】:2018-02-22 10:10:25 【问题描述】:

我正在为聊天应用程序设计一个 webapp。我有一个返回消息列表的 API:

chatsite.com/api/thread/1/messages/

[
    
        "id": 2,
        "sender": 
            "id": 2,
            "email": "usertwo@gmail.com"
        ,
        "sent_datetime": "2017-09-06T17:31:30Z",
        "body": "user two sending a message in new thread (pk1)"
    ,
    
        "id": 1,
        "sender": 
            "id": 1,
            "email": "user@gmail.com"
        ,
        "sent_datetime": "2017-09-06T17:28:56Z",
        "body": "Nwe thread est body"
    
]

这就是现在 html 的布局方式:

<div id="Thread">
    <div id="Header"></div>
    <div id="MessageList">
        <div class="message">
            <p>message.body</p>
        </div>
        <div class="message">
            <p>message.body</p>
        </div>
        <div class="message">
            <p>message.body</p>
        </div>
    </div>
    <div id="Footer"></div>
</div>

及其相关的css:

#Thread 
    background-color: mediumseagreen;
    display: flex;
    flex-direction: column;
    overflow-y: hidden;
    height: 600px;


#Header 
    height: 100px;
    background-color: blueviolet;


#MessageList 
    background-color: deepskyblue;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow-y: auto;


.message 
    background-color: white;
    padding: 8px;
    border: 1px solid #f9f9f9;
    font-size: 30px;
    margin: 4px;


#Footer 
    height: 100px;
    background: red;

到目前为止,消息按从上到下的方式按最新消息排序。最新的在顶部,依此类推:

__________________
|                |
|     HEADER     |
|________________|
|                |
| Latest msg     |
|________________|
|                |
| 2nd latest msg |
|________________|
|                |
|                |
|                |
|                |
|________________|
|                |
|     FOOTER     |
|________________|

但我想像现在所有的消息传递平台一样以自下而上的方式获取消息。最新的在底部等等:

__________________
|                |
|     HEADER     |
|________________|
|                |
|                |
|                |
|                |
|________________|
|                |
| 2nd latest msg |
|________________|
|                |
| Latest msg     |
|________________|
|                |
|     FOOTER     |
|________________|

如果有帮助,我将使用 Vuejs 作为前端框架。

【问题讨论】:

你能从 API 中订购结果吗? 你不能简单地使用flex-direction: column-reverse吗? :) 【参考方案1】:

只是改变:

#MessageList 
    flex-direction: column;

#MessageList 
    flex-direction: column-reverse; /* this */

#Thread 
  background-color: mediumseagreen;
  display: flex;
  flex-direction: column;
  overflow-y: hidden;
  height: 100vh;


#Header 
  height: 25px;
  background-color: blueviolet;


#MessageList 
  background-color: deepskyblue;
  height: 100%;
  display: flex;
  flex-direction: column-reverse;
  overflow-y: auto;


.message 
  background-color: white;
  padding: 4px;
  border: 1px solid #f9f9f9;
  font-size: 1rem;
  margin: 4px;


#Footer 
  height: 100px;
  background: red;
<div id="Thread">
  <div id="Header"></div>
  <div id="MessageList">
    <div class="message">
      <p>Latest</p>
    </div>
    <div class="message">
      <p>Older</p>
    </div>
    <div class="message">
      <p>Oldest</p>
    </div>
  </div>
  <div id="Footer"></div>
</div>

【讨论】:

【参考方案2】:

您可以反转流程以及滚动条以将最后一条消息保留在容器底部。使用的 CSS:flex-direction:column-reverse; transform:scale(1,-1);

由于一个错误,flex-direction:column + flex:1 + overflow:auto 不工作,我添加了一个额外的包装器来获得一个有效的滚动条来滚动到旧消息,如果你愿意的话。最后显示在底部的页脚处。

例子

// demo purposefaking new messsage coming up .. nop down the list ;)
$(document).ready(function() 
  setInterval(function() 
    $("#buffer").append('<div class="message"><p>The latest message added to the list.<br/>'+Date()+'</p></div>');
  , 2000);
);
#Thread 
  background-color: mediumseagreen;
  display: flex;
  flex-direction: column;
  overflow-y: hidden;
  height: 600px;
  max-height: 100vh;/* added optionnal*/


#Header, #Footer 
  background-color: blueviolet;
  line-height:2em;
  color:white;;


#MessageList 
  background-color: deepskyblue;
  flex: 1;/* added */
  transform: scale(1, -1);/* added  mirror the box and the scrollbar*/
  overflow: auto;/* added */


#buffer 
  display: flex;/* added */
  flex-flow: column-reverse;/* added */
  counter-reset: msg/* added */


.message:before 
  content: 'message N°'counter(msg);/* added */
  color:purple;

.message:nth-child(odd):before
  color:lime


.message 
  counter-increment: msg;/* added */
  background-color: white;
  padding: 8px;
  border: 1px solid #f9f9f9;
  font-size: 20px;
  margin: 4px;
  transform: scale(1, -1)/* added make the message readable again */


#Footer 
  background: red;

body margin:0;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="Thread">
  <div id="Header">header any height</div>
  <div id="MessageList">
    <div id="buffer">
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
      <div class="message">
        <p>message.body</p>
      </div>
    </div>
  </div>
  <div id="Footer">footer any height</div>
</div>

pen to play with

【讨论】:

很酷,但是如果你用鼠标滚轮滚动它,它会向相反的方向滚动:) @Qwertiy 是的,确实如此,需要 10 秒的时间才能滚动到相反的方向,这对我来说不是问题,因为大多数人甚至都没有注意到它;)【参考方案3】:

setInterval(function () 
  var main = document.querySelector('main');
  var div = document.createElement('div');
  div.textContent = Date();
  main.appendChild(div);
  main.scrollTop = main.scrollHeight; // Yep, it's larger, but browser will handle that
, 1000);
html, body 
  height: 100%;
  margin: 0;


body 
  display: flex;
  flex-direction: column;


main 
  flex: 1 1 auto;
  overflow: auto;
  background: antiquewhite;
  display: flex;
  flex-direction: column;


main::before 
  content: "";
  flex: 1 0 0px;
<header>Header</header>
<main></main>
<footer>Footer</footer>

【讨论】:

以上是关于聊天应用程序的从下到上的布局设计的主要内容,如果未能解决你的问题,请参考以下文章

从下到上显示聊天消息

xcode - 从下到上的 TableView 行

Laravel 8 从下到上的路线顺序

基本切换()从下到上的幻灯片问题

iOS UIScrollView 以编程方式从下到上添加元素

从下到上的动画边框颜色变化?