Go开发简易聊天界面 CSS布局导致底部消息无法全部显示
问题描述
使用Go语言开发简易聊天应用时,CSS样式出现异常:预期页面完整展示所有消息段落,但消息内容累计到展示区域底部时,部分消息被遮挡无法正常显示,实际效果如下:
当前单文件整合的HTML/CSS/JavaScript代码如下:
<!DOCTYPE html> <html lang="en"> <head> <title>CodeChallenge</title> <style> .form { position: fixed; left: 0; bottom: 0; right: 0; background-color: #f9f9f9; border-top: 1px solid #78b8ef; padding: 5px 10px; } .form .placeholder, .form .input-message, .form button { display: block; margin-bottom: 5px; } .form .input-message { padding: 7px; border: 1px solid #ecebeb; border-radius: 4px; width: -webkit-fill-available; } .form button { width: 100%; color: white; padding: 7px 10px; border-radius: 4px; background-color: #78b8ef; border: 1px solid #5a9ed8; } .container { margin-bottom: 50px; } .container p { display: block; } </style> </head> <body> <div class="container"></div> <div class="form"> <form onsubmit="app.doSendMessage(); return false;"> <div class="placeholder"> <label>Hello <b class="username"></b>. Say something:</label> </div> <input class="input-message" type="text" placeholder="Enter message"> <button type="submit">Send</button> </form> </div> <script type="application/javascript"> var app = {} app.ws = undefined app.container = undefined app.print = function (message) { let el = document.createElement("p") el.innerHTML = message app.container.append(el) } app.doSendMessage = function () { var messageRaw = document.querySelector('.input-message').value app.ws.send(JSON.stringify({ Message: messageRaw })); var message = '<b>me</b>: ' + messageRaw app.print(message) } app.init = function () { if (!(window.WebSocket)) { alert('Your browser does not support WebSocket') return } var name = getCookie("username"); document.querySelector('.username').innerText = name app.container = document.querySelector('.container') app.ws = new WebSocket("ws://localhost:8081/socket/ws?username=" + name) app.ws.onopen = function () { fetch('http://localhost:8081/message?limit=50') .then(response=>response.json()) .then(data=>{ console.log(data) data.sort(function(a,b){ return new Date(a.RegisterDate) - new Date(b.RegisterDate); }); console.log(data) data.forEach(obj => { let message = '<b>' + obj.From + '</b>: ' + obj.Message + ' ' + obj.RegisterDate app.print(message) })}) .then(() => { var message = '<b>me</b>: connected' app.print(message) } ) } app.ws.onmessage = function (event) { var res = JSON.parse(event.data) var message = '' if (res.Type === 'New User') { message = 'User <b>' + res.From + '</b>: connected' } else if (res.Type === 'Leave') { message = 'User <b>' + res.From + '</b>: disconnected' } else { message = '<b>' + res.From + '</b>: ' + res.Message } app.print(message) } } window.onload = app.init function getCookie(cName) { const name = cName + "="; const cDecoded = decodeURIComponent(document.cookie); console.log(cDecoded) const cArr = cDecoded.split('; '); console.log(cDecoded) let res; cArr.forEach(val => { if (val.indexOf(name) === 0) res = val.substring(name.length); }) return res } </script> </body> </html>
故障原因
- 底部发送表单使用
position: fixed固定在视口底部,脱离正常文档流,原本给消息容器.container设置的margin-bottom: 50px远小于表单实际渲染高度(表单包含提示文本、输入框、按钮三个块级元素,加上内边距、外边距总高度约130px),导致靠近底部的消息被表单遮挡。 - 新消息追加到DOM后没有自动滚动逻辑,历史消息加载完成、新消息发送/接收时,页面不会自动定位到最新消息位置,需要手动拖动滚动条才能查看。
修复方法
- 调整消息容器底部留白:放弃硬编码固定margin值,在初始化逻辑中动态获取底部表单的实际高度,自动计算需要预留的底部空间,从根源避免内容被遮挡,同时优化消息段落的排版样式。
将原有CSS中.container和.container p的样式替换为:
在.container { padding: 0 10px; } .container p { display: block; margin: 8px 0; word-break: break-all; }app.init方法中,获取到container元素的代码后新增动态设置留白的逻辑:app.container = document.querySelector('.container') // 动态计算底部表单高度,设置对应留白,额外加10px避免内容贴边 const formEl = document.querySelector('.form') app.container.style.marginBottom = formEl.offsetHeight + 10 + 'px' - 新增自动滚动到底部逻辑:每次新增消息后,自动将页面滚动到最底部,保证最新消息始终可见。修改
app.print方法:app.print = function (message) { let el = document.createElement("p") el.innerHTML = message app.container.append(el) // 滚动到页面底部展示最新消息 window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }) }
修复效果
所有历史消息、实时接收/发送的消息都不会被底部表单遮挡,消息加载、新消息到来时页面会平滑滚动到最新消息位置,排版间距符合聊天应用的常规使用习惯。
内容的提问来源于stack exchange,提问作者Wincenty Bertoni Lech
相关产品推荐
相关产品推荐

