用户点击图片按钮后,弹出文件选择窗口供用户选择图片。之后我们可以在JavaScript代码中使用FileReader来将图片读取为base64格式的字符串形式进行发送。而base64格式的图片直接可以指定为图片的src,这样就可以将图片用img标签显示在页面了。
为此我们监听图片按钮的change事件,一但用户选择了图片,便显示到自己的屏幕上同时读取为文本发送到服务器。
将以下代码添加到hichat.js的init方法中。
www/scripts/hichat.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', '!your browser doesn\'t support fileReader', '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
//接收用户发来的图片 socket.on('img', function(imgData) { //通过一个newImg事件分发到除自己外的每个用户 socket.broadcast.emit('newImg', socket.nickname, imgData); }); 同时向hichat.js的init方法添加以下代码以接收显示图片。 this.socket.on('newImg', function(user, img) { that._displayImage(user, img); });
有个问题就是如果图片过大,会破坏整个窗口的布局,或者会出现水平滚动条,所以我们对图片进行样式上的设置让它最多只能以聊天窗口的99%宽度来显示,这样过大的图片就会自己缩小了。
#historyMsg img { max-width: 99%; }
但考虑到缩小后的图片有可能失真,用户看不清,我们需要提供一个方法让用户可以查看原尺寸大小的图片,所以将图片用一个链接进行包裹,当点击图片的时候我们打开一个新的窗口页面,并将图片按原始大小呈现到这个新页面中让用户查看。
所以最后我们实现的_displayNImage方法应该是这样的。
将以下代码添加到hichat.js的HiChat类中。
www/scripts/hichat.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>(' + date + '): </span> <br/>' + '<a href="' + imgData + '" target="_blank"><img src="' + imgData + '"/></a>'; container.appendChild(msgToDisplay); container.scrollTop = container.scrollHeight; }
再次启动服务器打开程序,我们可以发送图片了。
发送表情
文字总是很难表达出说话时的面部表情的,于是表情就诞生了。
前面已经介绍过如何发送图片了,严格来说,表情也是图片,但它有特殊之处,因为表情可以穿插在文字中一并发送,所以就不能像处理图片那样来处理表情了。
根据以往的经验,其他聊天程序是把表情转为符号,比如我想发笑脸,并且规定':)'这个符号代码笑脸表情,然后数据传输过程中其实转输的是一个冒号加右括号的组合,当每个客户端接收到消息后,从文字当中将这些表情符号提取出来,再用gif图片替换,这样呈现到页面我们就 看到了表情加文字的混排了。
你好,王尼玛[emoji:23]------>你好,王尼玛
上面形象地展示了我们程序中表情的使用,可以看出我规定了一种格式来代表表情,[emoji:xx],中括号括起来然后'emoji'加个冒号,后面跟一个数字,这个数字表示某个gif图片的编号。程序中,如果我们点击表情按扭,然后呈现所有可用的表情图片,当用户选择一个表情后,生成对应的代码插入到当前待发送的文字消息中。发出去后,每个人接收到的也是代码形式的消息,只是在将消息显示到页面前,我们将表情代码提取出来,获取图片编号,然后用相应的图片替换。