以前有開發過一個h5微直播項目,當時裏面也用到過聊天模塊部分,今天就在以前聊天部分的基礎上從新抽離模塊,開發了這個h5趣聊項目,功能效果比較相似微信聊天界面。採用html5+css3+Zepto+swiper+wcPop+flex等技術融合開發,實現了發送消息、表情(動圖),圖片、視頻預覽,添加好友/羣聊,右鍵長按菜單。另外新增了語音模塊、地圖定位模塊。總體功能界面效果比較接近微信聊天。javascript
項目運行效果圖:css
// ripple波紋效果 wcRipple({ elem: '.effect__ripple-fff', opacity: .15, speed: .5, bgColor: "#fff" }); wcRipple({ elem: '.effect__ripple', opacity: .15, speed: .5, bgColor: "#000" }); // 禁止長按彈出系統菜單 $("body").on("contextmenu", ".weChatIM__panel", function (e) { e.preventDefault(); }); // 頂部 「+」 菜單 $("#J__topbarAdd").on("click", function(e){ var _points = [e.clientX, e.clientY]; var contextMenuIdx = wcPop({ skin: 'contextmenu', shade: true,shadeClose: true,opacity: 0,follow: _points, style: 'background:#3d3f4e; min-width:3.5rem;', btns: [ {text: '<i class="iconfont icon-haoyou fs-40 mr-10"></i><span>添加好友</span>',style: 'color:#fff;', onTap(){ wcPop.close(contextMenuIdx); // 添加好友 var addfriendIdx = wcPop({ id: 'wcim_fullscreen', skin: 'fullscreen', title: '添加好友', content: $("#J__popupTmpl-addFriends").html(), position: 'right', opacity: .1, xclose: true, style: 'background: #f2f1f6;' }); }}, {text: '<i class="iconfont icon-qunliao fs-40 mr-10"></i><span>發起羣聊</span>',style: 'color:#fff;', onTap(){ wcPop.close(contextMenuIdx); // 發起羣聊 var addfriendIdx = wcPop({ id: 'wcim_fullscreen', skin: 'fullscreen', title: '發起羣聊', content: $("#J__popupTmpl-launchGroupChat").html(), position: 'right', opacity: .1, xclose: true, style: 'background: #f2f1f6;' }); }}, {text: '<i class="iconfont icon-bangzhu fs-40 mr-10"></i><span>幫助與反饋</span>',style: 'color:#fff;',} ] }); });
◆ 搖一搖模塊彈窗模板:html
<!-- …… 搖一搖加好友彈窗模板.End --> <div class="wcim__popup-tmpl"> <div id="J__popupTmpl-shakeFriends" style="display:none;"> <div class="wcim__popupTmpl tmpl-shakeFriends"> <div class="wcim__shakeFriends-panel"> <span class="btn-setShake J__shakeSetting"><i class="iconfont icon-shezhi c-9ea0a3 fs-45"></i></span> <div class="shake-ico"><i class="iconfont icon-yaoyiyao"></i></div> <div class="shake-loading"><div class="J__shakeLoading" style="display:none;"><img src="img/deng.gif" /><em>正在搜尋同一時刻搖晃手機的人</em></div></div> <!-- 信息 --> <div class="shake-box J__shakeInfoBox"> <!-- <div class="shake-info flexbox flex-alignc"> <img class="uimg" src="img/uimg/u__chat-img08.jpg" /> <div class="flex1"> <h2 class="name">大冪冪<i class="iconfont icon-nv c-ee4343"></i></h2> <label class="lbl clamp1">開森每一刻,天天都要美美噠!</label> </div> </div> --> </div> <div class="shake-item J__swtShakeItem"> <a class="active" href="javascript:;"><i class="iconfont icon-yonghu"></i><em>人</em></a> <a href="javascript:;"><i class="iconfont icon-qunzu"></i><em>羣組</em></a> </div> </div> </div> </div> </div> <!-- …… 搖一搖加好友彈窗模板.End -->
// >>> 【搖一搖加好友核心模塊】------------------------------------------ // 搖一搖加好友彈窗 $("#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("觸發搖一搖!"); $(".J__shakeInfoBox").html(""); $(".J__shakeLoading").fadeIn(300); // 消息模板 var shakeTpl = [ '<div class="shake-info flexbox flex-alignc">\ <img class="uimg" src="img/uimg/u__chat-img08.jpg" />\ <div class="flex1">\ <h2 class="name">大冪冪<i class="iconfont icon-nv c-f37e7d"></i></h2>\ <label class="lbl clamp1">開森每一刻,天天都要美美噠!</label>\ </div>\ </div>' ].join(""); setTimeout(function(){ $(".J__shakeLoading").fadeOut(300); $(".J__shakeInfoBox").html(shakeTpl); }, 1500); }, false); } }); }); // 切換搖一搖項目 $("body").on("click", ".J__swtShakeItem a", function(){ $(this).addClass("active").siblings().removeClass("active"); }); // 搖一搖設置 $("body").on("click", ".J__shakeSetting", function(){ wcPop({ skin: 'actionsheetMini', anim: 'footer', btns: [ { text: '<div class="flexbox flex-alignc"><span class="flex1">是否開啓震動</span> <span class="rpr-30"><input class="cp__checkboxPX-switch" type="checkbox" checked /></span></div>' }, { text: '搖到的歷史' }, ] }); });
◆ h5+js仿微信語音彈窗效果模塊:html5
// >>> 【按住說話核心模塊】------------------------------------------ // ...按住說話 var _voiceObj = $(".J__wdtVoice"), eY1 = 0, eY2 = 0, eY3 = 0, isDrag = true; var voiceIdx; var difftime = 0; function initVoice(){ _voiceObj.on("touchstart", function(e){ difftime = new Date(); if(!isDrag) return; isDrag = false; eY1 = e.originalEvent.targetTouches[0].pageY; _voiceObj.text("鬆開 結束"); // 彈窗提示 voiceIdx = wcPop({ id: 'wdtVoice', skin: 'toast', content: '<div style="margin-top:-10px;"><i class="iconfont icon-yuyin" style="font-size:65px;"></i><div style="line-height:32px;">手指上滑,取消發送</div></div>', style: 'border-radius:6px;height: 160px; width:160px;', time: 10, opacity: 0, }); _voiceObj.on("touchmove", function (e) { e.preventDefault(); eY3 = e.originalEvent.targetTouches[0].pageY; if(eY1 - eY3 < 150){ _voiceObj.text("鬆開 結束"); }else{ _voiceObj.text("鬆開手指,取消發送"); // 彈窗提示 $("#wdtVoice .popui__panel-cnt").html('<div style="margin-top:-10px;"><i class="iconfont icon-quxiao" style="font-size:65px;"></i><div style="background:#c53838; border-radius:3px; line-height:32px;">鬆開手指,取消發送</div></div>'); } }); }); _voiceObj.on("touchend", function (e) { e.preventDefault(); eY2 = e.originalEvent.changedTouches[0].pageY; _voiceObj.text("按住 說話"); // 錄音時間過短提示 if(new Date() - difftime < 1000){ // 彈窗提示 $("#wdtVoice .popui__panel-cnt").html('<div style="margin-top:-10px;"><i class="iconfont icon-gantan" style="font-size:65px;"></i><div style="line-height:32px;">錄音時間過短!</div></div>'); } else{ if (eY1 - eY2 < 150) { // 發送成功 submitData(); console.log("測試數據"); } else { // 取消發送 console.log("cancel"); } } // 關閉彈窗 setTimeout(function(){ wcPop.close(voiceIdx); }, 500); isDrag = true; }); }
◆ js獲取語音時長:java
// ...獲取語音時長 getVoiceTime(); function getVoiceTime(){ $("#J__chatMsgList li .audio").each(function () { var that = $(this), audio = that.find("audio")[0], duration; audio.load(); audio.oncanplay = function(){ duration = Math.ceil(audio.duration); if (duration == 'Infinity') { getVoiceTime(); } else { that.find(".time").text(duration + `''`); that.attr("data-time", duration); // 語音寬度% var percent = (duration / 60).toFixed(2) * 100 + 20 + '%'; that.css("width", percent); } } }); }