近來(lái)一直在做微信開(kāi)發(fā),涉及的東西很多,但是思路基本是從微信接口拿數(shù)據(jù)這樣一個(gè)流程。在開(kāi)發(fā)過(guò)程中,順便寫(xiě)了一個(gè)聊天頁(yè)面。個(gè)人感覺(jué)還不錯(cuò),所以把其中遇到的幾個(gè)知識(shí)點(diǎn)分享給大家。

整體的界面就是上面的樣子,排版方面的知識(shí)就不多說(shuō)了,畢竟我也不是做前端的,而且很多樣式都是直接從官網(wǎng)拿過(guò)來(lái)。還是主要說(shuō)一說(shuō)流程邏輯方面的知識(shí)。其實(shí)并沒(méi)有太深的學(xué)問(wèn),只要有基礎(chǔ)的Js,循環(huán),判斷語(yǔ)句就可以了。我主要想表達(dá)的還是實(shí)戰(zhàn)思路。接下來(lái)我先把問(wèn)題拋出來(lái),如果已經(jīng)想到了很好的方法大可不必再浪費(fèi)時(shí)間看下去了。
1,中框部分的聊天記錄顯示問(wèn)題(各部分均為獨(dú)立iframe框架)
難點(diǎn):因?yàn)轱@示的條數(shù)受限,假設(shè)只顯示最近5條,那么應(yīng)該是用時(shí)間倒序獲取5條數(shù)據(jù),這樣能實(shí)現(xiàn)最近5條數(shù)據(jù),但是顯示結(jié)果會(huì)是自上而下從晚到早。相反,如果按照時(shí)間順序提取5條,那么顯示順序沒(méi)問(wèn)題,可是獲取的5條數(shù)據(jù)卻不是最近的而是最早的。
2,與第1點(diǎn)同步的會(huì)出現(xiàn)每條發(fā)送信息的時(shí)間,但是每條數(shù)據(jù)后面跟著一串‘2017-01-20 15:30:23’肯定會(huì)很難看。理想的效果是,短時(shí)間內(nèi)(例如半小時(shí)內(nèi))就顯示一次發(fā)送時(shí)間,當(dāng)天聊天記錄就只顯示時(shí)分秒,今天以前的聊天就顯示年月日時(shí)分秒。如果判斷是否當(dāng)天還好說(shuō),可是判斷是否距離上一條記錄(嚴(yán)格來(lái)說(shuō)是上一條顯示時(shí)間的記錄)半小時(shí)以?xún)?nèi)就要?jiǎng)觿?dòng)腦筋了。
3,中框的聊天信息展示肯定要隨時(shí)更新的,如果你發(fā)送一條信息用post提交,相當(dāng)于刷新一次頁(yè)面還好理解。但是如果是收到一條信息又怎么能即時(shí)刷新呢。
4,倘若中框的聊天記錄有10條,窗口大小只能顯示5條,怎么能讓它顯示到最底部一條信息。當(dāng)然,你可以只讓它獲取到最近5條數(shù)據(jù),但是如果某一條數(shù)據(jù)內(nèi)容特別長(zhǎng),還是會(huì)出現(xiàn)滾動(dòng)條,還是不是顯示頁(yè)面底部。
5,發(fā)送信息采用ctrl+enter發(fā)送,因?yàn)槿绻话磂nter發(fā)送,就不能換行了。網(wǎng)上可以搜到相關(guān)代碼,但是很有可能出現(xiàn)ctrl+enter鍵按下時(shí),打開(kāi)新的窗口。所以我在下面會(huì)放上測(cè)試好的代碼。
6,當(dāng)聊天頁(yè)面處于關(guān)閉狀態(tài),收到新信息會(huì)有消息提醒。這一點(diǎn)比較容易就不說(shuō)了。另外一種情況,你在聊天頁(yè)面與某一個(gè)好友聊天時(shí),另一個(gè)或多個(gè)好友來(lái)消息時(shí),也需要在對(duì)應(yīng)的頭像和分組菜單有消息提醒。
7,發(fā)送消息方式一般采用post提交,提交后頁(yè)面刷新也能獲取到最新消息。但是如果提交信息用的是其它接口(比如用微信公眾號(hào)發(fā)送),就會(huì)首先獲取到接口返回的數(shù)據(jù)后才能算發(fā)送成功,才能進(jìn)行寫(xiě)入數(shù)據(jù)庫(kù)或其它操作。在這個(gè)過(guò)程可能會(huì)3到5秒,體驗(yàn)效果就會(huì)變差。所以建議采用ajax異步提交,并且提交后利用Js顯示到聊天主窗口(發(fā)送中狀態(tài)),當(dāng)收到ajax發(fā)送成功的反饋時(shí)刷新頁(yè)面,否則提示發(fā)送失敗。
針對(duì)以上的問(wèn)題,在下面一一解答或者直接粘貼代碼。
問(wèn)題一思路:把獲取到的最近5條信息遍歷出來(lái),逆序賦值給一個(gè)變量,然后把這個(gè)變量當(dāng)成html元素放到頁(yè)面。
$res= mysql_query(“select * from msg where sid= 23 and user=23 order bycreat_time? limit 0,5”);//從數(shù)據(jù)庫(kù)獲取最近5條數(shù)據(jù)
$str= ‘’;//聲明變量
While($rows = mysql_fetch_array($res))
{
$str = “
{$rows[‘name’]}{$rows[‘con’]}
”.$str;
}
Html部分
{$str}
問(wèn)題二思路:
是否當(dāng)天可以用拿到的時(shí)間與當(dāng)天日期進(jìn)行比較(如果字段有時(shí)分秒可以截取前10位)
判斷是否與上一條顯示時(shí)間相隔半小時(shí),就需要先聲明一個(gè)時(shí)間變量,當(dāng)每次需要顯示時(shí)間時(shí)就賦值一次。
這里還有一個(gè)問(wèn)題,因?yàn)轱@示時(shí)第一條信息是5條里面最早的,最后一條是最近的,然后獲取數(shù)據(jù)的順序正好相反。所以判斷時(shí)間是否相隔半小時(shí),是拿到的一條時(shí)間與下一條時(shí)間做比較。這當(dāng)然是不可能的。那么我想到的方法先把獲取的數(shù)據(jù)賦值給數(shù)組,再用數(shù)據(jù)遍歷輸出。

問(wèn)題三思路:在里加入一行代碼
讓這個(gè)頁(yè)面每5秒刷新一次。這當(dāng)然是個(gè)方法,只是不太好。原因很簡(jiǎn)單,頁(yè)面會(huì)不斷的閃動(dòng)也會(huì)占用服務(wù)器承載量。所以建議用ajax獲取是否有新消息,如果有,則啟動(dòng)刷新。
functionget_msg(){
var str = '';
$.get("./ajax/ajax_wechat_new_list.php?uid="+uid+"&mid="+mid,function(data,status){
if(data>0){
window.location.reload();
}
});
setTimeout(function(){
get_msg();
},3000)
}
get_msg();
問(wèn)題四思路:這個(gè)問(wèn)題是個(gè)很實(shí)用的問(wèn)題,曾很困擾。我嘗試用模擬點(diǎn)擊事件,自動(dòng)運(yùn)行js效果都不太好。其實(shí)最簡(jiǎn)單的方法是在頁(yè)面末端加一個(gè)全局選擇器,例如id.
然后在url地址尾處加一個(gè)#go_foot,,,倘若不好用的話(huà),再設(shè)置瞄點(diǎn)模擬點(diǎn)擊。
document.getElementById('go_foot').click();
問(wèn)題五思路:
$("#sms_content").keyup(function(event){
if(event.ctrlKey && event.which ==13)?????? //13等于回車(chē)鍵(Enter)鍵值,ctrlKey等于Ctrl
{
$('#send').trigger("click");
}
});
備注:其中‘sms_content’是input提交標(biāo)簽的Id, keyup(松開(kāi)按鍵)可以改為keydown(按下鍵盤(pán)),但是會(huì)出現(xiàn)打開(kāi)新窗口的情況。
問(wèn)題六思路:
預(yù)先給每個(gè)好友設(shè)置好提醒的html元素(id名需要與該好友的id相關(guān)聯(lián)以便查找),并處理隱藏狀態(tài)。當(dāng)用ajax獲取到該好友的新消息時(shí),則找到對(duì)應(yīng)標(biāo)簽變?yōu)轱@示狀態(tài)。
functionget_msg(){
var str = '';
$.get("./ajax/ajax_wechat_notice1.php?uid="+uid+"&show="+show,function(data,status){
if(data!=0){
varmsg = eval("("+data+")");
for(vari=0;i
{
varmid = msg[i].id;
vartime = msg[i].time;
varcon = msg[i].msg.substring(0,16)+'...';
$("#show_msg"+mid).show();
$("#show_msg"+mid).parent().prevAll('.time_tag').text(time);
$("#show_msg"+mid).parent().prevAll('.ext').children('.new_msg').text(con);
$("#show_msg"+mid).parent().parent().parent().prev().prev('.group_user').children('img').show();
}
}
});
setTimeout(function(){
get_msg();
},10000);
}
get_msg();
備注:以上代碼在消息提醒的同時(shí),也會(huì)獲取到未讀消息的發(fā)送時(shí)間和內(nèi)容,需要在相關(guān)頁(yè)面設(shè)置,僅供參考。

問(wèn)題七思路:首先在中框聊天列表的頁(yè)面里,預(yù)先插入一條備用聊天記錄(包括發(fā)送人,發(fā)送信息,發(fā)送中狀態(tài)圖標(biāo)),使其隱藏狀態(tài)。當(dāng)點(diǎn)擊發(fā)送時(shí),需要處理幾個(gè)動(dòng)作。a,利用ajax把文本框內(nèi)容發(fā)送,b,文本框的內(nèi)容賦值給備用聊天記錄,c,令備用聊天記錄可見(jiàn),同時(shí)文本框內(nèi)容清空d,模擬點(diǎn)擊事件讓聊天頁(yè)面顯示底部,f,獲取ajax發(fā)送反饋,如果成功則刷新聊天記錄窗口。如果失敗利用js把發(fā)送中圖標(biāo)改為失敗圖標(biāo),并且彈出發(fā)出失敗的反饋信息。

