如何修复文本框位置并向消息添加滚动功能



我正在用 React 编写一个聊天应用程序。Messenger组件的当前设计有一个左侧边栏,一个中央块和一个右侧边栏。理想情况下,中央块的底部是一个固定大小的文本框,从顶部到块到文本框顶部的其余空间是消息区域,允许在溢出时滚动。

但是,我不确定如何将"滚动"和固定大小的文本框功能添加到我的应用程序中。目前,文本框的开头尾随最后一条消息之后,当最后一条消息超过垂直屏幕大小时,文本框不可见。

有人可以建议如何做到这一点吗?这是我的反应代码,只有基本元素和App.css。如果需要,请随时请求更多代码。

应用.js

import React, { Component } from "react";
import "./App.css";
import classNames from "classnames";
import "./App.css";
// Components
import _ from "lodash";
const MESSENGER_HEIGHT = "height";
const MESSENGER_NEW_MESSAGE = "newMessage";
const MESSENGER_SEARCH_USER = "searchUser";
const MESSENGER_SHOW_SEARCH_USER = "showSearchUser";
const MESSENGER_ACTIVE_CHANNEL_ID = "channel_id";
const MESSENGER_MEMBERS = "members";
const MESSENGER_MESSAGES = "messages";
const MESSENGER_CHANNELS = "channels";
const MESSENGER_PROFILE_ID = "profile_id";
//remove the authentication routes

class App extends Component {
constructor(props) {
super(props);
this.state = {};
const locals = this.state;
locals[MESSENGER_HEIGHT] = window.innerHeight;
locals[MESSENGER_NEW_MESSAGE] = "";
locals[MESSENGER_SEARCH_USER] = "";
locals[MESSENGER_SHOW_SEARCH_USER] = false;
locals[MESSENGER_ACTIVE_CHANNEL_ID] = "Mk3d9WJRiyifxgtJ1Ep1"; //TODO: trial run set default one
locals[MESSENGER_MEMBERS] = ["person1", "person2"];
locals[MESSENGER_MESSAGES] = [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13"
];
locals[MESSENGER_CHANNELS] = [];
locals[MESSENGER_PROFILE_ID] = "Testing profile_id";
}
render() {
let component_variable = null;
let members_list;
//About the presence system
if (this.state.members.length > 0) {
members_list = (
<div>
<h2 className="title">Members</h2>
<div className="members">
{this.state.members.map(member => {
return (
<div className="member">
<div className="member-info">
<h2> {member}</h2>
</div>
</div>
);
})}
</div>
</div>
);
} else {
members_list = null;
}
let search_bar = null;
let messages_list;
if (this.state.messages !== undefined) {
messages_list = (
<div>
<div ref={ref => (this.messagesRef = ref)} className="messages">
{this.state.messages.map(message => {
return (
<div className={classNames("message", { me: true })}>
<div className="message-body">
<div className="message-author">{"You "} says:</div>
<div className="message-text">
{`Testing message ${message}`}
</div>
<div className="message-timestamp">Some Date</div>
</div>
</div>
);
})}
</div>
</div>
);
} else {
messages_list = null;
}
let text_box;
if (this.state.members.length > 0) {
text_box = (
<div className="messenger-input">
<div className="text-input">
<textarea
onKeyUp={this.handle_textbox_keyup}
onChange={this.handle_textbox_set_state}
value={this.state["newMessage"]}
placeholder="Write your message..."
/>
</div>
<div className="actions">
<button onClick={() => this.handleSend()} className="send">
Send
</button>
</div>
</div>
);
} else {
text_box = null;
}
return (
<div className="app-messenger">
<div className="header">
<div className="left">
<button className="left-action">
<i className="icon-settings-streamline-1" />
</button>
<button
onClick={this.handle_create_channel}
className="right-action"
>
<i className="icon-edit-modify-streamline" />
</button>
<h2>Messenger</h2>
</div>
<div className="content" />
<div className="right">Hello world</div>
</div>
<div className="main">
<div className="sidebar-left">
<div className="chanels">
{this.state.channels.map((channel, key) => {
return (
<div
onClick={key => {
this.props.select_or_create_message_room({
id: channel._id
});
}}
key={channel._id}
className={classNames("chanel", {
notify: _.get(channel, "notify") === true
})}
>
<div className="channel-id">
{channel[MESSENGER_ACTIVE_CHANNEL_ID]}
</div>
</div>
);
})}
</div>
</div>
<div className="content">
{messages_list},{text_box}
</div>
{/*TODO: Member list*/}
<div className="sidebar-right">{members_list}</div>
</div>
</div>
);
}
}
export default App;

应用.css

html,
/*body {*/
/*  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',*/
/*    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',*/
/*    sans-serif;*/
/*  background-color: rgb(245, 245, 245);*/
/*}*/
.container {
margin: 80px auto 0 auto;
max-width: 1200px;
/*Cannot hidden bc the home screen is ugly*/
}
.nav-container {
margin: auto;
}
.nav-container svg {
color: #fff;
}
a {
text-decoration: none;
}

body, html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
body {
color: #2c3e50;
font-size: 13px;
font-family: 'Open Sans', sans-serif;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0; }
.app-messenger {
display: flex;
flex-direction: column;
}
.app-messenger .header {
height: 50px;
display: flex;
flex-direction: row;
border-bottom: 1px solid rgba(0, 0, 0, 0.05); }
.app-messenger .header .left {
width: 200px;
position: relative; }
.app-messenger .header .left .left-action {
position: absolute;
left: 8px;
top: 0; }
.app-messenger .header .left .right-action {
position: absolute;
right: 8px;
top: 0; }
.app-messenger .header .left h2 {
line-height: 50px;
font-size: 14px;
font-weight: 600;
display: block;
text-align: center; }
.app-messenger .header .left button {
background: none;
line-height: 50px;
border: 0 none;
font-size: 20px;
cursor: pointer; }
.app-messenger .header .content {
flex-grow: 1;
}
.app-messenger .header .content h2 {
line-height: 50px;
text-align: center; }
.app-messenger .header .right {
width: 300px; }
.app-messenger .header .right .user-bar {
line-height: 50px;
display: flex;
justify-content: flex-end;
padding: 0 10px; }
.app-messenger .header .right .user-bar .profile-name {
padding-right: 10px; }
.app-messenger .header .right .user-bar .profile-image {
line-height: 50px; }
.app-messenger .header .right .user-bar .profile-image img {
width: 30px;
height: 30px;
border-radius: 50%;
margin: 10px 0 0 0; }
.app-messenger .main {
height: 100%;
display: flex;
overflow: hidden; }
.app-messenger .main .sidebar-left {
width: 200px;
border-right: 1px solid rgba(0, 0, 0, 0.05); }
.app-messenger .main .sidebar-right {
border-left: 1px solid rgba(0, 0, 0, 0.05);
width: 300px; }
.app-messenger .main .sidebar-right .title {
padding: 10px; }
.app-messenger .main .content {
flex-grow: 1;
overflow: scroll;
display: flex;
flex-direction: column; }
.app-messenger .main .content .messages {
flex-grow: 1; }
.app-messenger .main .content .messenger-input {
border-top: 1px solid rgba(0, 0, 0, 0.05);
height: 50px;
display: flex;
flex-direction: row;
}
.app-messenger .main .content .messenger-input .text-input {
flex-grow: 1; }
.app-messenger .main .content .messenger-input .text-input textarea {
border: 0 none;
width: 100%;
height: 100%;
padding: 8px 15px; }
.app-messenger .main .content .messenger-input .actions button.send {
background: #2ecc71;
color: #FFF;
border: 0 none;
padding: 7px 15px;
line-height: 50px; }
.messages {
display: flex;
flex-direction: column;
overflow-y: auto;
height: 100%; }
.messages .message {
display: flex;
flex-direction: row;
justify-content: flex-start;
margin: 15px; }
.messages .message .message-user-image img {
width: 20px;
height: 20px;
border-radius: 50%; }
.messages .message .message-body {
padding-left: 10px; }
/*Try adding it manually, by right should make a message card, but will lose colour */
.messages .message .message-body .message-text {
background: rgba(0, 0, 0, 0.05);
padding: 10px;
border-radius: 10px; }

.messages .message.me {
justify-content: flex-end; }
.messages .message.me .message-body .message-text {
background: #2ecc71;
color: #FFF; }
.chanels {
overflow-y: auto;
height: 100%; }
.chanels .chanel {
cursor: pointer;
display: flex;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
padding: 8px; }
.chanels .chanel .user-image {
width: 30px; }
.chanels .chanel .user-image img {
max-width: 100%; }
.chanels .chanel .user-image .channel-avatars {
overflow: hidden;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #ccc;
position: relative; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-1 img {
width: 100%;
height: 100%;
border-radius: 50%; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-2 img {
width: 50%;
height: 100%;
position: absolute;
right: 0;
top: 0; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-2 img:first-child {
left: 0;
top: 0; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-3 img {
position: absolute;
width: 50%;
height: 50%;
right: 0;
top: 0; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-3 img:first-child {
left: 0;
top: 0;
width: 50%;
height: 100%; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-3 img:last-child {
bottom: 0;
right: 0;
top: 15px;
width: 50%;
height: 50%; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-4 img {
position: absolute;
width: 50%;
height: 50%;
right: 0;
top: 0; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-4 img:first-child {
left: 0;
top: 0;
width: 50%;
height: 100%; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-4 img:nth-child(3n) {
bottom: 0;
right: 0;
top: 15px;
width: 50%;
height: 50%; }
.chanels .chanel .user-image .channel-avatars.channel-avatars-4 img:last-child {
left: 0;
bottom: 0;
top: 15px; }
.chanels .chanel .chanel-info {
flex-grow: 1;
padding-left: 8px;
padding-right: 8px;
overflow: hidden; }
.chanels .chanel .chanel-info h2 {
font-size: 13px;
font-weight: 400;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden; }
.chanels .chanel .chanel-info p {
font-size: 12px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden; }
.chanels .chanel.active {
background: rgba(0, 0, 0, 0.05); }
.chanels .chanel.notify .chanel-info p {
color: #2ecc71; }
.members .member {
display: flex;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
padding: 8px; }
.members .member .member-info {
padding-left: 8px;
flex-grow: 1; }
.members .member .member-info h2 {
font-size: 14px; }
.members .member .member-info p {
font-size: 12px; }
h2.title {
font-size: 16px;
font-weight: 600;
color: rgba(0, 0, 0, 0.8); }

.app-message {
line-height: 1.5em;
padding: 10px;
font-size: 12px;
text-align: center;
border: 1px solid #2ecc71;
border-radius: 5px;
margin: 0 0 10px 0; }
.app-message.error {
background: #e74c3c;
color: #FFF;
border-color: #e74c3c; }

/*# sourceMappingURL=app.css.map */

CodeSandBox 上也提供可运行版本

您需要在.messages上设置max-height

.messages {
display: flex;
flex-direction: column;
overflow-y: auto;
height: 100%;
max-height: 500px;
}

最新更新