使用 node + express + socket 来一个即时聊天~

首先需要在电脑安装Node.js 如果基础不好的话看下官网了解一下
然后我们就可以搭建一个简单的HTTP服务器了

下面搭建一个简单的服务器了解一下不是正文
首先在文件目录里创建server.js内容为:

//引入http模块
var http = require('http'),
    //创建一个服务器
    server = http.createServer(function (req, res) {
        res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); // 这个是中文防乱码
        res.write('随便写点东西!!!');
        res.end();
    });
//监听80端口
server.listen(666);
console.log('服务器在666端口打开');

然后在终端输入:node server 就会提示 服务器在666端口打开
然后在浏览器输入http://localhost:666/就可以看到我们写的 ‘随便写点东西!!!’ 内容

然后下面开始进入正文
首先安装一下express 命令为 : npm install express 回车进行安装
然后在server.js中通过require('express')将其引入
express是node.js中管理路由响应请求的模块,根据请求的URL返回相应的HTML页面。这里我们使用一个事先写好的静态页面返回给客户端,只需使用express指定要返回的页面的路径即可。如果不用这个包,我们需要将HTML代码与后台JavaScript代码写在一起进行请求的响应,比较麻烦。

在存放上一步创建的server.js文件的地方,我们新建一个文件夹名字public用来存放我们的网页文件,包括图片以及前端的js文件等。假设已经在public文件夹下写好了一个index.html文件(将在下一步介绍,这一步你可以放一个空的HTML文件),则可以通过以下方式使用express将该页面返回到浏览器。可以看到较最开始,我们的服务器代码简洁了不少。
那么 下一步我们创建一个public文件夹 里面先创建一个index.html文件以及index.css文件

index.html

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="author" content="Wayou">
    <meta name="description" content="hichat | a simple chat application built with node.js and websocket">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>骚聊</title>
    <!-- 引入css样式 -->
    <link rel="stylesheet" href="./index.css">
    <!-- 这里先引入socket 以及 index.js 先引入一下一会讲解 -->
    <script src="/socket.io/socket.io.js"></script>
    <script src="./index.js"></script>
</head>

<body>
    <div class="wrapper">
        <div class="banner">
            <h1>开始聊骚吧</h1>
            <!-- 顶部的人数显示 -->
            <span id="status"></span>
        </div>
        <!-- historyMsg 写发送的内容的 -->
        <div id="historyMsg">
        </div>
        <div class="controls">
            <div class="items">
                <input id="colorStyle" type="color" placeHolder='#000' title="font color" />
                <input id="emoji" type="button" value="emoji" title="emoji" />
                <label for="sendImage" class="imageLable">
                    <input type="button" value="image" />
                    <input id="sendImage" type="file" value="image" />
                </label>
                <input id="clearBtn" type="button" value="clear" title="clear screen" />
            </div>
            <!-- 发送内容的input框 -->
            <textarea id="messageInput" placeholder="请输入骚掉牙的话"></textarea>
            <input id="sendBtn" type="button" value="发送">
            <div id="emojiWrapper">
            </div>
        </div>
    </div>
    <div id="loginWrapper">
        <p id="info">服务器连接中...</p>
        <!-- 服务器了解成功后显示这个 nickWrapper -->
        <div id="nickWrapper">
            <!-- 对应的让这个文本框获取焦点 -->
            <input type="text" placeholder="请输入骚气点的名字" id="nicknameInput" />
            <input type="button" value="OK" id="loginBtn" />
            <!-- 点击名字的确定按钮 -->
        </div>
    </div>
</body>
<!-- <script type="text/javascript">
        var socket = io.connect(),//与服务器进行连接
            button = document.getElementById('sendBtn');
        button.onclick = function () {
            socket.emit('foo', 'hello');//发送一个名为foo的事件,并且传递一个字符串数据‘hello’
        }
    </script> -->

</html>

这里先引入 socket 以及 index.js 一会讲解 socket 是需要下载的 index.js是自己创建的

index.css

html,
body {
    margin: 0;
    background-color: #efefef;
    font-family: sans-serif;
}

.wrapper {
    width: 500px;
    height: 640px;
    padding: 5px;
    margin: 0 auto;
    background-color: #ddd;
}

#loginWrapper {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(5, 5, 5, .6);
    text-align: center;
    color: #fff;
    display: block;
    padding-top: 200px;
}

#nickWrapper {
    display: none;
}

.banner {
    height: 80px;
    width: 100%;
}

.banner p {
    float: left;
    display: inline-block;
}

.controls {
    height: 100px;
    margin: 5px 0px;
    position: relative;
}

#historyMsg {
    height: 400px;
    background-color: #fff;
    overflow: auto;
    padding: 2px;
}

#historyMsg img {
    max-width: 99%;
}

.timespan {
    color: #ddd;
}

.items {
    height: 30px;
}

#colorStyle {
    width: 50px;
    border: none;
    padding: 0;
}

/*custom the file input*/

.imageLable {
    position: relative;
}

#sendImage {
    position: absolute;
    width: 52px;
    left: 0;
    opacity: 0;
    overflow: hidden;
}

/*end custom file input*/

#messageInput {
    width: 440px;
    max-width: 440px;
    height: 90px;
    max-height: 90px;
    float: left;
}

#sendBtn {
    width: 50px;
    height: 96px;
    float: right;
}

#emojiWrapper {
    display: none;
    width: 500px;
    bottom: 105px;
    position: absolute;
    background-color: #aaa;
    box-shadow: 0 0 10px #555;
}

#emojiWrapper img {
    margin: 2px;
    padding: 2px;
    width: 25px;
    height: 25px;
}

#emojiWrapper img:hover {
    background-color: blue;
}

.emoji {
    display: inline;
}

footer {
    text-align: center;
}

ok 到这步后简单的页面以及样式就已经排好了,当然还差一步就是在server.js去设置
server.js

var express = require('express'), //引入express模块
    app = express(),
    server = require('http').createServer(app);
app.use('/', express.static(__dirname + '/public')); //指定静态HTML文件的位置
server.listen(666);

这样的输入node server 就可以看到搭建的简单样式了 那么功能如何实现呢?

在Node.js中使用socket的一个包。使用它可以很方便地建立服务器到客户端的sockets连接,发送事件与接收特定事件。
同样通过npm进行安装 npm install socket.io 安装后在node_modules文件夹下新生成了一个socket.io文件夹,其中我们可以找到一个socket.io.js文件。将它引入到HTML页面,这样我们就可以在前端使用socket.io与服务器进行通信了。
刚才已经引入过了

同时服务器端的server.js里跟使用express一样,也要通过require('socket.io')将其引入到项目中,这样就可以在服务器端使用socket.io了。
使用socket.io,其前后端句法是一致的,即通过socket.emit()来激发一个事件,通过socket.on()来侦听和处理对应事件。这两个事件通过传递的参数进行通信。具体工作模式可以看下面这个示例。

下面咱们在index.html进行测试,简单了解一下

上面有个button按钮就不写了
<script>
	var socket=io.connect(),//与服务器进行连接
		button=document.getElementById('sendBtn');
	button.onclick=function(){
		socket.emit('foo', 'hello');//发送一个名为foo的事件,并且传递一个字符串数据‘hello’
	}
</script>

然后server.js配置如下

//服务器及页面响应部分
var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server); //引入socket.io模块并绑定到服务器
app.use('/', express.static(__dirname + '/public'));
server.listen(666);
console.log("服务器在666端口打开")
//socket部分
io.on('connection', function (socket) {
    //接收并处理客户端发送的foo事件
    socket.on('foo', function (data) {
        //将消息输出到控制台
        console.log(data);
    })
});

这样的话点击过后再终端就会输出hello 现在主要是了解一下这个 测试完删掉即可

有了上面一些了解,下面可以进入骚聊的功能开发了

此刻打开页面我们看到的是一个淡黑色的遮罩层,而接下来我们要实现的是用户暱称的输入与服务器登入。这个遮罩层用于显示连接到服务器的状态信息,而当连接完成之后,会出现一个输入框用于暱称输入。
也就是意味着我们只要连接成功就可以输入骚气点的名称了

之前我们已经把index.js引入页面了那么开始搞吧
首先在index.js里
定义一个全局变量用于我们整个程序的开发HiChat(名字随便起),
同时使用window.onload在页面准备好之后实例化HiChat,调用其init方法运行我们的程序。

window.onload = function() {
    //实例并初始化我们的hichat程序
    var hichat = new HiChat();
    hichat.init();
};

//定义我们的hichat类
var HiChat = function() {
    this.socket = null;
};

//向原型添加业务方法
HiChat.prototype = {
    init: function() {//此方法初始化程序
        var that = this;
        //建立到服务器的socket连接
        this.socket = io.connect();
        //监听socket的connect事件,此事件表示连接已经建立
        this.socket.on('connect', function() {
            //连接到服务器后,显示暱称输入框
            document.getElementById('info').textContent = '请输入一个骚气的名字';
            document.getElementById('nickWrapper').style.display = 'block';
            document.getElementById('nicknameInput').focus();
        });
    }
};

上面的代码定义了整个程序需要使用的类HiChat,之后我们处理消息显示消息等所有业务逻辑均写在这个类里面。
首先定义了一个程序的初始化方法,这里面初始化socket,监听连接事件,一旦连接到服务器,便显示暱称输入框。当用户输入暱称后,便可以在服务器后台接收到然后进行下一步的处理了。
这样我们从新运行就可以看到请输入骚气的名字了
下面呢
我们要求连接的用户需要首先设置一个暱称,且这个暱称还要唯一,也就是不能与别人同名。一是方便用户区分,二是为了统计在线人数,同时也方便维护一个保存所有用户暱称的数组。
为此在后台server.js中,我们创建一个名叫users的全局数组变量,当一个用户设置好暱称发送到服务器的时候,将暱称压入users数组。同时注意,如果用户断线离开了,也要相应地从users数组中移除以保证数据的正确性。
在前台,输入暱称点击OK提交后,我们需要发起一个设置暱称的事件以便服务器侦听到。将以下代码添加到之前的init方法中。
index.js

//暱称设置的确定按钮
 //名字的确定按钮
        document.getElementById('loginBtn').addEventListener('click', function () {
            var nickName = document.getElementById('nicknameInput').value;
            // nicknameInput 输入名字的input框
            //检查暱称输入框是否为空
            if (nickName.trim().length != 0) {
                //不为空,则发起一个login事件并将输入的暱称发送到服务器
                that.socket.emit('login', nickName);
            } else {
                //否则输入框获得焦点
                document.getElementById('nicknameInput').focus();
            };
        }, false);

server.js


//服务器及页面响应部分
var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server); //引入socket.io模块并绑定到服务器
    users = [];//这个用于存放一些用户
app.use('/', express.static(__dirname + '/public'));
server.listen(666);
console.log("服务器在666端口打开")
//socket部分
// io.on('connection', function (socket) {
//     //接收并处理客户端发送的foo事件
//     socket.on('foo', function (data) {
//         //将消息输出到控制台
//         console.log(data);
//     })
// });
io.sockets.on('connection', function (socket) {
    //login 这里的login就是咱点击输入名字的login
    socket.on('login', function (nickname) {
        if (users.indexOf(nickname) > -1) {
            socket.emit('nickExisted');
        } else {
            //socket.userIndex = users.length;
            socket.nickname = nickname;
            users.push(nickname);
            socket.emit('loginSuccess');
            io.sockets.emit('system', nickname, users.length, 'login');
        };
    });


})

需要解释一下的是,在connection事件的回调函数中,socket表示的是当前连接到服务器的那个客户端。所以代码socket.emit(‘foo’)则只有自己收得到这个事件,而socket.broadcast.emit(‘foo’)则表示向除自己外的所有人发送该事件,另外,上面代码中,io表示服务器整个socket连接,所以代码io.sockets.emit(‘foo’)表示所有人都可以收到该事件。
上面代码先判断接收到的暱称是否已经存在在users中,如果存在,则向自己发送一个nickExisted事件,在前端接收到这个事件后我们显示一条信息通知用户。

接下来添加一段代码在index.js中

this.socket.on('nickExisted', function() {
     document.getElementById('info').textContent = '这个骚气的名字已经被占用'; //显示暱称被占用的提示
 });

如果暱称没有被其他用户占用,则将这个暱称压入users数组,同时将其作为一个属性存到当前socket变量中,并且将这个用户在数组中的索引(因为是数组最后一个元素,所以索引就是数组的长度users.length)也作为属性保存到socket中,后面会用到。最后向自己发送一个loginSuccess事件,通知前端登陆成功,前端接收到这个成功消息后将灰色遮罩层移除显示聊天界面。

将下面代码添加到index.js的init方法中。

this.socket.on('loginSuccess', function() {
     document.title = 'hichat | ' + document.getElementById('nicknameInput').value;
     document.getElementById('loginWrapper').style.display = 'none';//隐藏遮罩层显聊天界面
     document.getElementById('messageInput').focus();//让消息输入框获得焦点
 });

// 用户离开 在 server.js
//断开连接的事件

socket.on('disconnect', function() {
    //将断开连接的用户从users中删除
    users.splice(socket.userIndex, 1);
    //通知除自己以外的所有人
    socket.broadcast.emit('system', socket.nickname, users.length, 'logout');
});

然后在index.js中的init方法中

this.socket.on('system', function(nickName, userCount, type) {
     //判断用户是连接还是离开以显示不同的信息
     var msg = nickName + (type=='login'?'上线':'离线');
     var p = document.createElement('p');
     p.textContent = msg;
     document.getElementById('historyMsg').appendChild(p);
     //将在线人数显示到页面顶部
     document.getElementById('status').textContent = userCount + (userCount > 1 ? ' users' : ' user') + ' 在线';
 });

现在运行程序,打开多个浏览器标签,然后登陆离开,你就可以看到相应的系统提示消息了。

下面开始发送消息
用户连接以及断开我们需要显示系统消息,用户还要频繁的发送聊天消息,所以可以考虑将消息显示到页面这个功能单独写一个函数方便我们调用。为此我们向HiChat类中添加一个_displayNewMsg的方法,它接收要显示的消息,消息来自谁,以及一个颜色共三个参数。因为我们想系统消息区别于普通用户的消息,所以增加一个颜色参数。同时这个参数也方便我们之后实现让用户自定义文本颜色做准备。
不是init了哈是HiChat类里面

//向原型添加业务方法
HiChat.prototype = {
    init: function() { //此方法初始化程序
        //...
    },
    _displayNewMsg: function(user, msg, color) {
        var container = document.getElementById('historyMsg'),
            msgToDisplay = document.createElement('p'),
            date = new Date().toTimeString().substr(0, 8);
        msgToDisplay.style.color = color || '#000';
        msgToDisplay.innerHTML = user + '<span class="timespan">(' + date + '): </span>' + msg;
        container.appendChild(msgToDisplay);
        container.scrollTop = container.scrollHeight;
    }
};

在_displayNewMsg方法中,我们还向消息添加了一个日期。我们也判断了该方法在调用时有没有传递颜色参数,没有传递颜色的话默认使用#000即黑色。

同时修改我们在system事件中显示系统消息的代码,让它调用这个_displayNewMsg方法。

index.js

 this.socket.on('system', function (nickName, userCount, type) {
            var msg = nickName + (type == 'login' ? ' 上线' : ' 下线');
            //指定系统消息显示为红色
            that._displayNewMsg('用户 ', msg, 'red');
            document.getElementById('status').textContent = userCount + (userCount > 1 ? ' users' : ' user') + ' 在线';
        });

有了这个显示消息的方法后,下面就开始实现用户之间的聊天功能了。
做法也很简单,如果你掌握了上面所描述的emit发送事件,on接收事件,那么用户聊天消息的发送接收也就轻车熟路了。
首先为页面的发送按钮写一个click事件处理程序,我们通过addEventListner来监听这个click事件,当用户点击发送的时候,先检查输入框是否为空,如果不为空,则向服务器发送postMsg事件,将用户输入的聊天文本发送到服务器,由服务器接收并分发到除自己外的所有用户。

将以下代码添加到index.js的init方法中。

index.js

document.getElementById('sendBtn').addEventListener('click', function() {
    var messageInput = document.getElementById('messageInput'),
        msg = messageInput.value;
    messageInput.value = '';
    messageInput.focus();
    if (msg.trim().length != 0) {
        that.socket.emit('postMsg', msg); //把消息发送到服务器
        that._displayNewMsg('me', msg); //把自己的消息显示到自己的窗口中
    };
}, false);

在server.js中添加代码以接收postMsg事件。

server.js

// 信息内容
    socket.on('postMsg', function (msg, color) {
        socket.broadcast.emit('newMsg', socket.nickname, msg, color);
    });

然后在客户端接收服务器发送的newMsg事件,并将聊天消息显示到页面。

将以下代码显示添加到index.js的init方法中了。

this.socket.on('newMsg', function(user, msg) {
    that._displayNewMsg(user, msg);
});

运行程序,现在可以发送聊天消息了。

发送图片
上面已经实现了基本的聊天功能了,进一步,如果我们还想让用户可以发送图片,那程序便更加完美了。

图片不同于文字,但通过将图片转化为字符串形式后,便可以像发送普通文本消息一样发送图片了,只是在显示的时候将它还原为图片。

在这之前,我们已经将图片按钮在页面放好了,其实是一个文件类型的input,下面只需在它身上做功夫便可。

用户点击图片按钮后,弹出文件选择窗口供用户选择图片。之后我们可以在JavaScript代码中使用FileReader来将图片读取为base64格式的字符串形式进行发送。而base64格式的图片直接可以指定为图片的src,这样就可以将图片用img标签显示在页面了。

为此我们监听图片按钮的change事件,一但用户选择了图片,便显示到自己的屏幕上同时读取为文本发送到服务器。

将以下代码添加到index.js的init方法中。

index.js

document.getElementById('sendImage').addEventListener('change', function() {
    //检查是否有文件被选中
     if (this.files.length != 0) {
        //获取文件并用FileReader进行读取
         var file = this.files[0],
             reader = new FileReader();
         if (!reader) {
             that._displayNewMsg('system', '这里是错误信息', 'red');
             this.value = '';
             return;
         };
         reader.onload = function(e) {
            //读取成功,显示到页面并发送到服务器
             this.value = '';
             that.socket.emit('img', e.target.result);
             that._displayImage('me', e.target.result);
         };
         reader.readAsDataURL(file);
     };
 }, false);

上面图片读取成功后,调用_displayNImage方法将图片显示在自己的屏幕同时向服务器发送了一个img事件,在server.js中,我们通过这个事件来接收并分发图片到每个用户。同时也意味着我们还要在前端写相应的代码来接收。

这个_displayNImage还没有实现,将会在下面介绍。

将以下代码添加到server.js的socket回调函数中。

server.js

 //image
    socket.on('img', function (imgData, color) {
        socket.broadcast.emit('newImg', socket.nickname, imgData, color);
    });

同时向index.js的init方法添加以下代码以接收显示图片。

 this.socket.on('newImg', function(user, img) {
     that._displayImage(user, img);
 });

但考虑到缩小后的图片有可能失真,用户看不清,我们需要提供一个方法让用户可以查看原尺寸大小的图片,所以将图片用一个链接进行包裹,当点击图片的时候我们打开一个新的窗口页面,并将图片按原始大小呈现到这个新页面中让用户查看。

所以最后我们实现的_displayNImage方法应该是这样的。

将以下代码添加到index.js的HiChat类中。

index.js

_displayImage: function(user, imgData, color) {
    var container = document.getElementById('historyMsg'),
        msgToDisplay = document.createElement('p'),
        date = new Date().toTimeString().substr(0, 8);
    msgToDisplay.style.color = color || '#000';
    msgToDisplay.innerHTML = user + '<span class="timespan">(' + date + '): </span> <br/>' + '<a href="' + imgData + '" target="_blank"><img src="' + imgData + '"/></a>';
    container.appendChild(msgToDisplay);
    container.scrollTop = container.scrollHeight;
}

发送表情
我们使用兔斯基作为我们聊天程序的表情包。可以看到,有很多张gif图,如果手动编写的话,要花一些功夫,不断地写<img src='*****.gif'/>,所以考虑将这个工作交给代码来自动完成,写一个方法来初始化所有表情。

为此将以下代码添加到HiChat类中,并在init方法中调用这个方法。

index.js

_initialEmoji: function() {
    var emojiContainer = document.getElementById('emojiWrapper'),
        docFragment = document.createDocumentFragment();
    for (var i = 69; i > 0; i--) {
        var emojiItem = document.createElement('img');
        emojiItem.src = './emoji/' + i + '.gif';
        emojiItem.title = i;
        docFragment.appendChild(emojiItem);
    };
    emojiContainer.appendChild(docFragment);
}
_showEmoji: function (msg) {
        var match, result = msg,
            reg = /\[emoji:\d+\]/g,
            emojiIndex,
            totalEmojiNum = document.getElementById('emojiWrapper').children.length;
        while (match = reg.exec(msg)) {
            emojiIndex = match[0].slice(7, -1);
            if (emojiIndex > totalEmojiNum) {
                result = result.replace(match[0], '[X]');
            } else {
                result = result.replace(match[0], '<img class="emoji" src="./emoji/' + emojiIndex + '.gif" />');//todo:fix this in chrome it will cause a new request for the image
            };
        };
        return result;
    }

同时将以下代码添加到index.js的init方法中。

this._initialEmoji();
 document.getElementById('emoji').addEventListener('click', function(e) {
     var emojiwrapper = document.getElementById('emojiWrapper');
     emojiwrapper.style.display = 'block';
     e.stopPropagation();
 }, false);
 document.body.addEventListener('click', function(e) {
     var emojiwrapper = document.getElementById('emojiWrapper');
     if (e.target != emojiwrapper) {
         emojiwrapper.style.display = 'none';
     };
 });

上面向页面添加了两个单击事件,一是表情按钮单击显示表情窗口,二是点击页面其他地方关闭表情窗口。

现在要做的就是,具体到某个表情被选中后,需要获取被选中的表情,然后转换为相应的表情代码插入到消息框中。

为此我们再写一个这些图片的click事件处理程序。将以下代码添加到index.js的init方法中。

index.js

document.getElementById('emojiWrapper').addEventListener('click', function(e) {
    //获取被点击的表情
    var target = e.target;
    if (target.nodeName.toLowerCase() == 'img') {
        var messageInput = document.getElementById('messageInput');
        messageInput.focus();
        messageInput.value = messageInput.value + '[emoji:' + target.title + ']';
    };
}, false);

现在表情选中后,消息输入框中可以得到相应的代码了。

之后的发送也普通消息发送没区别,因为之前已经实现了文本消息的发送了,所以这里不用再实现什么,只是需要更改一下之前我们用来显示消息的代码,首先判断消息文本中是否含有表情符号,如果有,则转换为图片,最后再显示到页面。

为此我们写一个方法接收文本消息为参数,用正则搜索其中的表情符号,将其替换为img标签,最后返回处理好的文本消息。

将以下代码添加到HiChat类中。

index.js

_showEmoji: function(msg) {
    var match, result = msg,
        reg = /\[emoji:\d+\]/g,
        emojiIndex,
        totalEmojiNum = document.getElementById('emojiWrapper').children.length;
    while (match = reg.exec(msg)) {
        emojiIndex = match[0].slice(7, -1);
        if (emojiIndex > totalEmojiNum) {
            result = result.replace(match[0], '[X]');
        } else {
            result = result.replace(match[0], '<img class="emoji" src="../content/emoji/' + emojiIndex + '.gif" />');
        };
    };
    return result;
}

现在去修改之前我们显示消息的_displayNewMsg方法,让它在显示消息之前调用这个_showEmoji方法。

_displayNewMsg: function (user, msg, color) {
        //historyMsg 发送的内容
        var container = document.getElementById('historyMsg'),
            msgToDisplay = document.createElement('p'),
            date = new Date().toTimeString().substr(0, 8);
            //将消息中的表情转化为图片
        msg = this._showEmoji(msg);
        msgToDisplay.style.color = color || '#000';
        msgToDisplay.innerHTML = user + '<span class="timespan">(' + date + '): </span>' + msg;
        container.appendChild(msgToDisplay);
        container.scrollTop = container.scrollHeight;
    },

_showEmoji这个我重复写了一下 反正就一个 注意一个就好了 这里我不进行修改了

文字颜色
HTML5新增了一个专门用于颜色选取的input标签,并且Chrome对它的支持非常之赞,直接弹出系统的颜色拾取窗口。
IE及FF中均是一个普通的文本框,不过不影响使用,只是用户只能通过输入具体的颜色值来进行颜色设置,没有Chrome里面那么方便也直观。

之前我们的_displayNewMsg方法可以接收一个color参数,现在要做的就是每次发送消息到服务器的时候,多加一个color参数就可以了,同时,在显示消息时调用_displayNewMsg的时候将这个color传递过去。

下面是修改index.js中消息发送按钮代码的示例:

document.getElementById('sendBtn').addEventListener('click', function() {
    var messageInput = document.getElementById('messageInput'),
        msg = messageInput.value,
        //获取颜色值
        color = document.getElementById('colorStyle').value;
    messageInput.value = '';
    messageInput.focus();
    if (msg.trim().length != 0) {
        //显示和发送时带上颜色值参数
        that.socket.emit('postMsg', msg, color);
        that._displayNewMsg('me', msg, color);
    };
}, false);

同时修改index.js中接收消息的代码,让它接收颜色值

this.socket.on('newMsg', function(user, msg, color) {
     that._displayNewMsg(user, msg, color);
 });

这只是展示了发送按钮的修改,改动非常小,只是每次消息发送时获取一下颜色值,同时emit事件到服务器的时候也带上这个颜色值,这样前端在显示时就可以根据这个颜色值为每个不两只用户显示他们自己设置的颜色了。剩下的就是按相同的做法把发送图片时也加上颜色,这里省略。

清空

 //清空
        document.getElementById('clearBtn').addEventListener('click', function () {
            document.getElementById('historyMsg').innerHTML = '';
        }, false);

按键操作
将以下代码添加到index.js的init方法中,这样在输入暱称后,按回车键就可以登陆,进入聊天界面后,回车键可以发送消息。

document.getElementById('nicknameInput').addEventListener('keyup', function(e) {
      if (e.keyCode == 13) {
          var nickName = document.getElementById('nicknameInput').value;
          if (nickName.trim().length != 0) {
              that.socket.emit('login', nickName);
          };
      };
  }, false);
  document.getElementById('messageInput').addEventListener('keyup', function(e) {
      var messageInput = document.getElementById('messageInput'),
          msg = messageInput.value,
          color = document.getElementById('colorStyle').value;
      if (e.keyCode == 13 && msg.trim().length != 0) {
          messageInput.value = '';
          that.socket.emit('postMsg', msg, color);
          that._displayNewMsg('me', msg, color);
      };
  }, false);

现在搞完了可以添加一个package.json文件
这样别人就可以拷贝过来过去我的代码了

{
    "name": "ssl",
    "description": "a realtime chat web application",
    "version": "0.4.0",
    "main": "server.js",
    "dependencies": {
        "express": "3.4.x",
        "socket.io": "0.9.x"
    },
    "engines": {
        "node": "0.10.x",
        "npm": "1.2.x"
    }
}

最后我把他上传到了gitHub:https://github.com/user-sunshilin/-
现在这个文件是更新了一下 github上面的是之前写的 不影响一点点程序跑起来
拿到过后 npm install 下载依赖包 然后 node server 跑起来

当然也可以部署到线上~
写好过后 就开始愉快的聊天吧~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章