相信你们都有使用过微信,微信这款产品确实设计的不错,简约不简单。尤为里面的摇一摇、语音功能更是吸引了大批用户,颠覆式的功能及设计,让微信稳稳坐上了社交宝座。css
以前因为项目需求有开发过一款简单的聊天项目,不过功能及UI比较简单,最近又从新在原先的基础上进行了一次大的重构,开发了这款仿微信界面聊天IM系统——趣聊weChatIM。html
基于html5+css3+Zepto+swiper+wcPop+flex等技术混合开发,实现了发送消息、表情(动图),图片、视频预览,添加好友/群聊,右键长按菜单。另外新增了语音模块、地图定位模块。总体功能界面效果比较接近微信聊天。html5
介绍了这么多,一睹效果吧:node
怎么样,看了效果图,是否是感受还不错,棒棒哒。css3
引入css及js插件以下:chrome
另外项目中使用的弹窗wcPop.js,是本身开发的移动端弹窗组件,兼容全部移动设备(亲测),多种api调用方式及动画效果;
嗯,效果统一,的确不错。api
摇一摇功能,基于shake.js插件微信
$("#J__popScreen_shake").on("click", function () { var shakePopIdx = wcPop({ id: 'wcim_shake_fullscreen', skin: 'fullscreen', title: '摇一摇', content: $("#J__popupTmpl-shakeFriends").html(), position: 'right', xclose: true, style: 'background: #303030;', show: function(){ // 摇一摇功能 var _shake = new Shake({threshold: 15}); _shake.start(); window.addEventListener("shake", function(){ window.navigator.vibrate && navigator.vibrate(500); // console.log("触发摇一摇!"); //...逻辑代码 setTimeout(function(){ $(".J__shakeLoading").fadeOut(300); $(".J__shakeInfoBox").html(shakeTpl); }, 1500); }, false); } }); });
聊天模块代码片断架构
// ...滚动聊天区底部 function wchat_ToBottom() { $(".mescroll").animate({ scrollTop: $("#J__chatMsgList").height() }, 0); }
// ...处理编辑器信息 var $editor = $(".J__wdtEditor"), _editor = $editor[0]; function surrounds() { setTimeout(function () { //chrome var sel = window.getSelection(); var anchorNode = sel.anchorNode; if (!anchorNode) return; if (sel.anchorNode === _editor || (sel.anchorNode.nodeType === 3 && sel.anchorNode.parentNode === _editor)) { var range = sel.getRangeAt(0); var p = document.createElement("p"); range.surroundContents(p); range.selectNodeContents(p); range.insertNode(document.createElement("br")); //chrome sel.collapse(p, 0); (function clearBr() { var elems = [].slice.call(_editor.children); for (var i = 0, len = elems.length; i < len; i++) { var el = elems[i]; if (el.tagName.toLowerCase() == "br") { _editor.removeChild(el); } } elems.length = 0; })(); } }, 10); }
编辑器框插入表情处理app
if (that.hasClass("face")) { //小表情 var img = that[0].cloneNode(true); if (!_editor.childNodes.length) { _editor.focus(); } _editor.blur(); //输入表情时禁止输入法 setTimeout(function () { if (document.selection && document.selection.createRange) { document.selection.createRange().pasteHTML(img); } else if (window.getSelection && window.getSelection().getRangeAt) { range = _rng.getRange(); range.insertNode(img); range.collapse(false); _lastRange = range; //记录当前光标位置 (不然光标会跑到表情前面) _rng.addRange(); } }, 10); }
判断编辑器内容是否为空
function isEmpty() { var html = $editor.html(); html = html.replace(/<br[\s\/]{0,2}>/ig, "\r\n"); html = html.replace(/<[^img].*?>/ig, ""); html = html.replace(/ /ig, ""); return html.replace(/\r\n|\n|\r/, "").replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, "") == ""; }
地图模块,采用的是百度地图api
// ...选择位置 var poiPopIdx; $(".J__chooseWz").on("click", function () { poiPopIdx = wcPop({ id: 'wcim_local_fullscreen', title: '位置', skin: 'fullscreen', content: $("#J__popupTmpl-location").html(), position: 'right', xclose: true, style: 'background: #f3f3f3;', // 加载地图 show: function () { $(".J__sendLatlng").show(); $(".localMap").html('<iframe id="mapPage" width="100%" height="100%" frameborder=0 src="https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&referer=myapp"></iframe>'); } }); }); // ...获取位置坐标点 var pointArr; window.addEventListener('message', function (event) { // 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息 var loc = event.data; // 防止其余应用也会向该页面post信息,需判断module是否为'locationPicker' if (loc && loc.module == 'locationPicker') { console.log('location', loc); pointArr = loc; } }, false);