Knockout : 实现复杂的web聊天窗体
公司以前一个同事写的这个聊天的窗体,由于是采用了html拼接的方式,外加处理的时候没有合理的划分职责,导致页面js代码量非常庞大(1500行左右)。现在这哥们离职了,苦的是我们剩下的人,不多说,我先去擦把泪。
公司基本没周都要求给web聊天加各种各样的功能,然后各种不能忍,权衡之后只能选择重构代码,可怜的娃娃啊。。。。
本次完全采用Knockout重构,基础的东西就不多说了,学习Knockout请移步大叔的blog(多谢大叔无私分享) http://www.cnblogs.com/TomXu/archive/2011/11/21/2257154.html
上web聊天界面截图:

view代码:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>后台聊天</title>
<link rel="stylesheet" href="css/jquery.qqFace-min.css" />
<link rel="stylesheet" href="css/index0923.css" />
<style type="text/css">
/* style="display:none;" */
</style>
</head> <body>
<div class="chatDiv" id="chatDiv" style="border:1px solid #ededed;">
<!-- 单聊 -->
<div id="singleChat">
<!-- 聊天联系人列表 -->
<div class="chatLp">
<!--div class="title"><a href="###" class="clearAll">清空</a></div-->
<div class="title">
<a href="###" class="sendAll l">群发</a>
<a href="javascript:void(0);" class="delete r" data-bind="click:function(){viewModel.clearArray();}"></a>
</div>
<ul class="chatList" data-bind="template:{ name: 'demo',foreach:viewModel.viewModelArray}">
<!--<li><i class="ico icoOne"></i><i class="come"></i><span class="txt">八卦台湾</span></li>
<li class="select"><i class="ico icoOne"></i><span class="txt">八卦台湾</span></li>
<li><img class="ico" src="data:images/img.png"/><span class="txt">八卦台湾</span></li>--> </ul>
</div>
<div class="chatRp">
<div class="chatName" data-bind="template:{ name: 'title',foreach:viewModel.selectViewModel}"> </div>
<!-- 对话内容 -->
<div class="content">
<div id="chatMain" class="chatMain" style="overflow-y: scroll;" tabindex="5001" data-bind="template:{ name: 'content',foreach:viewModel.selectModel}"> </div>
<div class="speakInp">
<span class="spaeakBtn biaoq"></span>
<span class="spaeakBtn edit"></span>
<textarea class="textarea-txt" style="overflow: hidden;" data-bind="value:textContent"></textarea>
<a class="sub_btn" href="javascript:void(0);" data-bind="click:function(){viewModel.msgPush();}">发送</a>
</div>
</div>
</div>
<div class="clearB"></div>
</div>
</div>
<div>
<button data-bind="click:add">Add</button>
</div>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/jquery.qqFace-min.js"></script>
<script type="text/javascript" src="js/jquery.nicescroll.min.js"></script>
<script src="js/jquery.tmpl.js"></script>
<script src="js/knockout-2.0.0.debug.js"></script>
<script type="text/x-jquery-tmpl" id="demo"> <li data-bind="click:function() {viewModel.select($data)},css:{select:$data.data()==viewModel.selectModel()},
event: { mouseover:function(){ viewModel.showCloseIco($data,true);}, mouseout: function(){ viewModel.showCloseIco($data,false);} }"> <img class="ico" data-bind="css:{icoOne:$data.data().length>0}" src="${ico}"></img>
<span class="txt">${name}</span>
<i class="icodelete" data-bind="click:function () {viewModel.remove($data)},style:{display:$data.isShow()== true?'inline':'none'}"></i>
</li> </script> <script type="text/x-jquery-tmpl" id="content">
<div class="anotherIetm" data-bind="css:{selfIetm:$data.msgtype }">
<div class="icoP"><img src="${ico}" class="ico"></div>
<div class="contentP">
<span class="name">${name}</span>
<div class="speakCon">
<span class="jiao"></span>
<div class="mainCont">${msg}</div>
<div class="clearB"></div>
</div>
</div>
<div class="clearB"></div>
</div>
</script> <script type="text/x-jquery-tmpl" id="title">
<span class="left">${name}</span>
<span class="right">
<span>您的身份:[${serverId}]</span>
</span>
<div class="clearB"></div>
</script> <script src="ChatModel.js"></script>
<script src="ChatViewModel.js"></script>
</body>
</html>
Model代码:
/// <reference path="js/knockout-2.0.0.debug.js" />
function LeftObject(ico, name, serverid) {
this.ico = ico;
this.name = name;
this.isShow = ko.observable();
this.data = ko.observableArray();
this.serverId = serverid;
} function MsgContent(msgtype, msg, name, ico) {
this.msgtype = msgtype;
this.msg = msg;
this.name = name;
this.ico = ico;
}
ViewModel代码:
/// <reference path="js/knockout-2.0.0.debug.js" />
//======================左边用户列表操作===========================
var num = 0;
var viewModel = {
add: function () {
num = num + 1;
viewModel.viewModelArray.push(new LeftObject("http://www.baidu.com/img/bdlogo.png", "Test" + num,"客服-应用主"));
if (viewModel.selectModel().length == 0) {
viewModel.selectModel(viewModel.viewModelArray()[viewModel.viewModelArray().length - 1].data());
viewModel.selectViewModel(viewModel.viewModelArray()[viewModel.viewModelArray().length - 1]);
}
},
push: function () {
if (viewModel.selectModel()) {
viewModel.selectModel.push({ content: num, isSend: (num % 2 == 1) })
}
},
viewModelArray: ko.observableArray()
};
viewModel.remove = function (e) {
viewModel.viewModelArray.remove(e); if (viewModel.selectModel() == e.data()) {
viewModel.selectModel([]);
}
viewModel.selectModel(viewModel.viewModelArray()[0].data());
viewModel.selectViewModel(viewModel.viewModelArray()[0]);
}
viewModel.select = function (e) {
viewModel.selectModel(e.data());
viewModel.selectViewModel(e);
}
viewModel.selectModel = ko.observableArray();
viewModel.selectViewModel = ko.observable(); viewModel.showCloseIco = function (e,isShow) {
e.isShow(isShow);
//alert(e.isShow());
} viewModel.clearArray = function () {
viewModel.viewModelArray([]);
} //===========================分割线 下面是聊天窗口操作函数=========================================== viewModel.msgAccept = function (data) {
viewModel.selectModel.push(new MsgContent(true, data, "自己", "images/ico.png"));
} viewModel.msgSend = function (data) {
viewModel.selectModel.push(new MsgContent(false, data, "别人", "images/img.png"));
}
viewModel.textContent = ko.observable();
//模拟发送
viewModel.msgPush = function (data) { if (viewModel.viewModelArray().length == 0) {
return;
}
var d = parseInt( Math.random()*10 % 2);
data = viewModel.textContent();
viewModel.textContent('');
if (d == 0) {
viewModel.msgSend(data);
} else {
viewModel.msgAccept(data);
}
} //=====================================================================
ko.applyBindings(viewModel);
Knockout : 实现复杂的web聊天窗体的更多相关文章
- 高仿webqq做的一个webos桌面效果和web聊天工具,桌面效果完好,功能强大
QQ技术交流群:159995692 /-------- 暂时开放的測试 帐号/password:[88888888/1;666666/1] ---------/ 正如大家所知的E ...
- 使用Servlet和JSP实现一个简单的Web聊天室系统
1 问题描述 利用Java EE相关技术实现一个简单的Web聊天室系统,具体要求如下. (1)编写一个登录 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室 实战系列
ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 http://www.cnblogs.com/panzi/p/5742089.html ASP.NET S ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十二) 代码重构使用反射工厂解耦(一)缓存切换
前言 上一篇中,我们用了反射工厂来解除BLL和UI层耦合的问题.当然那是最简单的解决方法,再复杂一点的程序可能思路相同,但是在编程细节中需要考虑的就更多了,比如今天我在重构过程中遇到的问题.也是接下来 ...
- web聊天室
开发一个web聊天室 功能需求: 1.用户可以与好友一对一聊天 2.群聊 所需知识 1.Django 2.bootstrap 3.CSS 4.ajax 涉及到的新的知识点 1.如果设计表结构的时候,一 ...
- 利用html 5 websocket做个山寨版web聊天室(手写C#服务器)
在之前的博客中提到过看到html5 的websocket后很感兴趣,终于可以摆脱长轮询(websocket之前的实现方式可以看看Developer Works上的一篇文章,有简单提到,同时也说了web ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言
前端时间听一个技术朋友说 LayIM 2.0 发布了,听到这个消息抓紧去官网看了一下.(http://layim.layui.com/)哎呀呀,还要购买授权[大家支持一下哦],果断买了企业版,喜欢钻研 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)
大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(二) 之 ChatServer搭建,连接服务器,以及注意事项。
上篇:ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取) 上一篇我们已经完成了初步界面的搭建工作,本篇将介绍IM的核心内容 ...
随机推荐
- USACO Section 2.4 回家 Bessie Come Home
题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只最快的母牛). 在挤奶 ...
- WebService之基于REST机制的实现实例(Java版)
REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移).2000年Roy Fielding博士在他的博士论文“Architectural Sty ...
- 学习练习 java面向对象封装汽车
package com.hanqi; //汽车 public class Car { // 车牌 private String CheP; // 油箱容量 private double YouXRL ...
- ubuntu 更新重启后 登录后 无法进入图形界面
切换到控制台然后看看-/.Xauthority的组属性是否正确,如果被改成root组了,就会造成不能登陆,你将其删除就ok了
- 华为OJ平台——百钱买百鸡问题
题目描述: 元前五世纪,我国古代数学家张丘建在<算经>一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一. 百钱买百鸡,问鸡翁.鸡母.鸡雏各几何? 思路: 这道题很简单,假 ...
- powerdesigner逆向导出oracle数据库结构显示备注
最近接到命令,要将oracle数据库的结构导出为pdm文件供其他同事使用,逆向工程导出数据库结构比较方便,但是发现导出的数据库结构没有注释,这是很郁闷的事情: 查过网上很多资料都是sqlserver的 ...
- 用Scrapy爬虫下载图片(豆瓣电影图片)
用Scrapy爬虫的安装和入门教程,这里有,这篇链接的博客也是我这篇博客的基础. 其实我完全可以直接在上面那篇博客中的代码中直接加入我要下载图片的部分代码的,但是由于上述博客中的代码已运行,已爬到快九 ...
- Leetcode049. Group Anagrams
//hashmap implement with STL class Solution { public: vector<vector<string>> groupAnagra ...
- PAT1020. Tree Traversals
//典型后中省树,这种方法必须有 中序序列来确定根的位置,然后二分建树: //因为用的vc,之前用序列位置建树通不过,用坐标建树通过了,怀疑vc的功能限制,有时间再来测试,眼下感觉还是坐标好啊,用地址 ...
- HTML5-新API选择器
新的选择器document.querySelector("selector");selector:根据CSS选择器返回第一个匹配到的元素,如果没有匹配到,则返回null;支持: C ...