仿ChatGPT对话前端页面(内含源码)
- 前言
- 布局
- 样式和Js部分关键点
- 全部源码
前言
本文主要讲解如何做出类似ChatGPT的前端页面。具体我们的效果图是长这样,其中除了时间是动态的之外,其他都是假数据。接下来让我们从布局和样式的角度分析,如何做出来这样的页面,同时文末有全部源码,需要自取。
布局
- 主要利用flex和position定位进行布局。
- 首先是用左右布局作为大的布局分工,而最大的布局方式用的是Flex弹性盒子布局,并且用
justify-content: center;align-content: center;
对盒子进行水平垂直居中。接下来讲解左右两边布局。 - 左侧布局占据flex:1,我们发现这里有个按钮来控制视图显示隐藏,这个按钮用的是定位中的父元素
relative
和子元素absolute
控制垂直居中,然后用点击事件click
来分别让左侧CSS的display
变成none
或者block
进行显示隐藏。 - 左侧 上面布局:着重讲一下前端性能优化那里,那里用了一个flex布局,那个边框里…,占据了
flex:1
,而右侧文字占据flex:8
- 左侧 下面布局:也是flex布局,左侧头像布局为
flex:1
,而右侧占据的是3,同时头像颜色是通过linear-gradient
进行设置,原角度是利用border-radius:50%
进行圆的绘制。 - 右侧布局:右侧布局又分为上下两部分,上部分是通过position定位中的绝对定位
absolute,top,right
属性来实现布局。 - 下部分是通过定位
position:absolute;bottom:0;right
来实现布局的 - 比较有意思的是,我在JavaScript中把时间变成了动态的,是通过new一个
Date
对象,然后把值赋给时间样式id的innerHTML
实现的。
样式和Js部分关键点
- input点击不出现黑色边框:
outline: none;
- 计算盒子宽高时候不计算它的边框和内边距:
box-sizing: border-box;
- 日期是
Date
日期对象自带的方法调用,创建了一个函数用于判断时间是否需要补0操作。
用的是三目表达式作为返回值。
全部源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
outline: none;
box-sizing: border-box;
}
body {
margin: 1vh 20px;
min-height: 98vh;
display: flex;
justify-content: center;
align-content: center;
/* border: 1px solid lightgray; */
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
}
.left_layout {
flex: 1;
border-right: 1px solid lightgray;
}
.right_layout {
flex: 6;
}
.father_icon {
position: relative;
}
.son_icon {
background-color: white;
z-index: 99;
position: absolute;
font-size: 20px;
border-radius: 50%;
border: 1px solid lightgray;
padding: 0px 5px;
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
color: gray;
}
.son_icon_display {
top: 48vh;
right: -15px;
}
.son_icon_hideen {
top: 48vh;
left: 10px;
display: none;
}
.new_chat {
border: 1px solid lightgray;
padding: 10px 20px;
margin: 20px 10px;
text-align: center;
}
.new_chat_text {
border: 1px solid green;
display: flex;
}
.left_person {
width: 100%;
padding: 1vh 20px;
/* margin:20px 10px; */
position: absolute;
top: 90vh;
border-top: 1px solid lightgray;
}
.false_img {
/* background:linear-gradient(-135deg,#0c80cc,#009dff); */
flex: 1;
}
.false_img_right {
flex: 3;
}
.flase_img_son {
width: 50px;
height: 50px;
background: linear-gradient(-135deg, #0000cc, #009dff);
border: 1px solid lightblue;
border-radius: 50%;
}
.right_layout_flex{
display:flex;
justify-content: center;
align-items: center;
}
.right_layout_son{
margin:0 auto 0 auto;
width:100vh;
height:98vh;
/* border:1px solid gray; */
position: relative;
}
.right_layout_son_ipt{
position: absolute;
bottom:0;
}
.btn{
border:none;
padding:10px 15px;
background-color: #18a058;
border-radius: 1px;
color:white;
}
.ipt{
width:85vh;
margin:10px 20px;
padding:10px 20px;
border:1px solid lightgray;
}
.right_layout_myselfChat{
width:200px;
position: absolute;
top:5px;
right:0;
display:flex;
}
.myself_chat{
position: absolute;
top:30px;
right:80px;
padding:10px 20px;
border-radius: 10px;
background-color: #7ae1b6;
opacity: 0.8;
}
</style>
</head>
<body>
<div id="sonHiddenIcon" class="son_icon son_icon_hideen" onclick="btn_display_icon()"></div>
<div class="left_layout" id="left_layout_id">
<div class="father_icon">
<div id="sonIcon" class="son_icon son_icon_display" onclick="btn_icon()"></div>
<div id="left_person" class="left_person">
<div style="display:flex;justify-content: center;align-items:center">
<div class="false_img">
<div class="flase_img_son"></div>
</div>
<div class="false_img_right">
<strong>Michael Jackson</strong>
</div>
</div>
</div>
</div>
<div class="new_chat">新建聊天</div>
<div class="new_chat new_chat_text">
<div class="false_img" style="border:1px solid lightgray;border-radius:20%;color:green;">...</div>
<div style="flex:8;color:green;">前端有哪些性能优化?</div>
</div>
</div>
<div class="right_layout">
<!-- <div class="right_layout_flex"> -->
<div class="right_layout_son">
<div class="right_layout_myselfChat">
<div id="datatime" style="flex:2;font-size:13px;color:lightgray"></div>
<div style="flex:1">
<div class="flase_img_son" style="width:40px;height:40px;"></div>
</div>
</div>
<div class="myself_chat">
前端有哪些性能优化?
</div>
<div class="right_layout_son_ipt">
<input class="ipt" type="text" placeholder="来说点什么吧...">
<button class="btn">发送</button>
</div>
</div>
<!-- </div> -->
</div>
<script>
let display_sonIcon = document.getElementById('sonIcon')
let hidden_sonIcon = document.getElementById('sonHiddenIcon')
let left_layout_id = document.getElementById('left_layout_id')
let myself_datetime=document.getElementById('datatime')
display_sonIcon.innerHTML = '<'
hidden_sonIcon.innerHTML = '>'
function btn_icon() {
left_layout_id.style.display = 'none'
hidden_sonIcon.style.display = 'block'
}
function btn_display_icon() {
left_layout_id.style.display = 'block'
hidden_sonIcon.style.display = 'none'
}
function isZero(num){
return (num < 10 ? '0' : '') + num;
}
function getDateTime(DOM){
let datetime=new Date;
let year=datetime.getFullYear();
let month=isZero(datetime.getMonth()+1);
let day=isZero(datetime.getDate());
let hour=isZero(datetime.getHours());
let minute=isZero(datetime.getMinutes());
let seconds=isZero(datetime.getSeconds());
let date=year+'/'+month+'/'+day+' '+hour+':'+minute+":"+seconds;
DOM.innerHTML=date
}
getDateTime(myself_datetime)
</script>
</body>
</html>