终于有点时间写点博客了,最近在忙着找工作的事情。在进入正题之前,我必须得感谢下PHP中文网的所有老师,他们让我对前端有了更清晰的理解。不管什么问题,一个人很难考虑的很全面,但是多个人就不一样了,每个人的出发点不同,思考方式或也不尽相同,人数多了想到的自然会很全面,一个项目的完成如果包含了很多人的努力,那么用户体验、业务逻辑等肯定会很棒。前端这个圈子说大不大,感谢大家给我一个温馨的大家庭。大家在一起学习,聊聊技术,彼此相互照应,挺好。闲话不多说了,且进入正题。
1.首先预览下页面效果:
2.布局的HTML文档没什么好说的,消息区域用无序列表。
index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>聊天室</title> <link rel="stylesheet" href="css/style.css"> <script src="js/move3.js" charset="utf-8"></script> <script src="js/javascript.js" charset="utf-8"></script> </head> <body> <div> <div> <div>仿微信聊天</div> <span id="time">00:00:00</span> </div> <ul id="chatContent"> </ul> <div> <input type="text" id="txt1"name="" value="" placeholder="请输入..."> <input type="button" id="btn" name="" value="发送"> </div> </div> </body> </html>
3.层叠样式表部分,浮动和绝对定位混合使用来定位
style.css
html,body,ul,li { margin: 0; padding: 0; list-style: none; } .chat { width: 450px; height: 770px; background: #eee; margin: 20px auto 0; box-shadow: 20px 20px 55px #777; } .chat .head { width: 450px; height: 45px; background-color: #000000; position: relative; } .chat .head .center { display: inline-block; position: absolute; left: 90px; width: 60%; height: 45px; text-align: center; color: #FFEFE4; line-height: 45px; font-weight: bolder; } .chat .head span { display: block; line-height: 45px; float: right; color: white; } .chat #chatContent { width: 450px; height: 660px; overflow: auto; } .chat .bottom{ width:434px; height: 49px; padding: 8px; background-color: #666666; } .chat .bottom #txt1{ width: 330px; height: 44px; /*outline: solid 1px;*/ border-radius: 6px; font-size: 20px; } .chat .bottom #btn { width: 80px; height: 47px; color: white; font-size: 22px; border-radius: 6px; /*background-color:#7DFC00;*/ background-color: #19AD17; border:0px; } .chat #chatContent li >img{ width: 30px; height: 30px; display: inline-block; border-radius: 50%; /*float: right;*/ } .chat #chatContent li>span { padding: 10px; /*float: right;*/ display: inline-block; margin: 6px 10px 0 10px; /*important*/ max-width: 310px; border: 1px solid #ccc; box-shadow: 0 0 3px #ccc; background-color: #7DFC00; border-radius: 6px; padding: 10px; } .chat #chatContent li { margin-top: 10px; padding-left: 10px; width: 412px; margin: 2px 0; display: block; clear: both; overflow: hidden; } .clear { clear: both; } .fl { float: left; } .fr { float: right; }
4.最重要的部分到了,原生JS实现人机交互和页面动态,具体的功能说明代码中我都加了注释
javascript.js
window.onload=function () { var oBtn=document.getElementById('btn'); var oTxt=document.getElementById('txt1'); var oUl=document.getElementById('chatContent'); var oTime=document.getElementById('time'); // 标准化时间 function toDouble(num) { if (num<10) { return '0'+num; }else { return ''+num; } } // 获取并返回时间字符串 var showTime=function () { var oDate=new Date(); var hour=oDate.getHours(); var min=oDate.getMinutes(); var sec=oDate.getSeconds(); return ''+toDouble(hour)+':'+toDouble(min)+':'+toDouble(sec); } // 设置定时器定时刷新时间 setInterval(function () { oTime.innerHTML=showTime(); },30); // enter键键盘点击事件 document.onkeydown=function (ev) { var oEvent=event||ev; if (oEvent.keyCode==13) { submit(); } } // 实现提交聊天内容 submit=oBtn.onclick=function () { var timeStr=showTime(); var oLi=document.createElement('li'); oLi.innerHTML += '<img src="image/me.jpg" class="fr"><span class="fr"><span style="color:yellow;font-size:16px;">'+timeStr+'</span><br>'+oTxt.value+'</span>'; donghua(); // oUl.appendChild(oLi); oTxt.value=''; var aData=['你好','吃饭没','吃饱了没','再来一瓶可乐','可以打包吗','您要买什么','我喜欢这条裤子','你要去哪里','这儿附近有饭馆吗']; var oLi=document.createElement('li'); oLi.innerHTML += '<img src="image/github1.jpg" class="fl"><span class="fl" ><span style="color:yellow;font-size:16px;">'+timeStr+'</span><br>'+aData[Math.floor(Math.random()*aData.length)]+'</span>'; donghua(); // oUl.appendChild(oLi); // 实现消息框延时滑出 function donghua() { oUl.appendChild(oLi); var iHeight=oLi.offsetHeight; oLi.style.height='0'; startMove(oLi,{height:iHeight},function(){ // 内容过多时加滚动条 oUl.scrollTop=oUl.scrollHeight; startMove(oLi,{opacity:100}); }); } } }
5.消息框延时滑出函数的定义部分
move3.js
function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; }else { return getComputedStyle(obj, false)[name]; } } function startMove(obj, json,fnEnd) { clearInterval(obj.timer); obj.timer=setInterval(function () { // 假设所有的属性值都到达了目标值 var bStop=true; for(var attr in json){ var cur=0; if (attr=='opacity') { cur=Math.round(parseFloat(getStyle(obj, attr))*100); }else { cur=parseInt(getStyle(obj,attr)); } var speed=(json[attr]-cur)/6; speed=speed>0?Math.ceil(speed):Math.floor(speed); if(cur!=json[attr]){ bStop=false; } if (attr=='opacity') { obj.style.filter='alpha(opacity:'+(cur+speed)+')'; obj.style.opacity=(cur+speed)/100; }else { obj.style[attr]=cur+speed+'px'; } } if (bStop) { clearInterval(obj.timer); // alert('abc'); if(fnEnd)fnEnd(); } },30); }
6.issue与后期改进
经过测试,发现当消息区域的消息满屏后,后面输入的内容会在下面,经过修改后,提交消息时滚动条会先猛的向下一滑,很不自然,然后消息框动画正常显示。第二,aData数组数据内容不够全面,甲发出一条消息后乙的回复是随机的,这样不太好。应该可以做出根据甲的内容,乙的回复符合人类日常用语的逻辑,微软小娜是个不错的好例子,完成这个功能应该需要字符串搜索等的技术的支持。第三,这个还仅仅是一个基于前端的项目,应该拓展一下,加入服务器端的功能,使其可以实现远程聊天。这些我有时间了会去尝试一下,欢迎大家给出好的建议和改进。