博客列表 >原生JS仿微信聊天

原生JS仿微信聊天

zhihuanwang的博客
zhihuanwang的博客原创
2017年12月18日 12:03:371123浏览

   终于有点时间写点博客了,最近在忙着找工作的事情。在进入正题之前,我必须得感谢下PHP中文网的所有老师,他们让我对前端有了更清晰的理解。不管什么问题,一个人很难考虑的很全面,但是多个人就不一样了,每个人的出发点不同,思考方式或也不尽相同,人数多了想到的自然会很全面,一个项目的完成如果包含了很多人的努力,那么用户体验、业务逻辑等肯定会很棒。前端这个圈子说大不大,感谢大家给我一个温馨的大家庭。大家在一起学习,聊聊技术,彼此相互照应,挺好。闲话不多说了,且进入正题。

        1.首先预览下页面效果:

20171218_115717.gif

    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数组数据内容不够全面,甲发出一条消息后乙的回复是随机的,这样不太好。应该可以做出根据甲的内容,乙的回复符合人类日常用语的逻辑,微软小娜是个不错的好例子,完成这个功能应该需要字符串搜索等的技术的支持。第三,这个还仅仅是一个基于前端的项目,应该拓展一下,加入服务器端的功能,使其可以实现远程聊天。这些我有时间了会去尝试一下,欢迎大家给出好的建议和改进。





声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
飞将军2017-12-18 13:44:351楼
学习了