主搞后端开发,前端技术不是很6,望大神勿喷!

环信官网的web-im api是一个巨坑,前端兄弟一脸懵逼,无奈只能帮前端兄弟写这个demo,一阵心酸和泪水~~~~

完整的资源下载地址:点击下载

片段如下:(只提供思路和基本demo,请勿喷代码风格和洁癖,毕竟我只是帮忙搞这个。。。。)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WebIM-17610510206</title>
<script type="text/javascript" src="jquery-1.11.1.js"></script>
<script type="text/javascript" src="strophe-custom-2.0.1.js"></script>
<script type="text/javascript" src="json2.js"></script>
<script type="text/javascript" src="easemob.im-1.0.7.js"></script>
<script type="text/javascript" src="bootstrap.js"></script>
<link rel="stylesheet" type="text/css" href="css/webim.css" />
<link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
<script type="text/javascript">var xmppURL = null;var apiURL = null;var curUserId = null;var curChatUserId = null;var conn = null;var curRoomId = null;var msgCardDivId = "chat01";var talkToDivId = "talkTo";var talkInputId = "talkInputId";var fileInputId = "fileInput";var bothRoster = [];var toRoster = [];var maxWidth = 200;var groupFlagMark = "group--";var groupQuering = false;var textSending = false;var appkey = "********";//你的环信appkeyvar time = 0;window.URL = window.URL || window.webkitURL || window.mozURL|| window.msURL;var getLoginInfo = function() {return {isLogin : false};};var showLoginUI = function() {$('#loginmodal').modal('show');$('#username').focus();};var hiddenLoginUI = function() {$('#loginmodal').modal('hide');};var showWaitLoginedUI = function() {$('#waitLoginmodal').modal('show');};var hiddenWaitLoginedUI = function() {$('#waitLoginmodal').modal('hide');};var showChatUI = function() {$('#content').css({"display" : "block"});var login_userEle = document.getElementById("login_user").children[0];login_userEle.innerHTML = curUserId;login_userEle.setAttribute("title", curUserId);};//登录之前不显示web对话框var hiddenChatUI = function() {$('#content').css({"display" : "none"});document.getElementById(talkInputId).value = "";};//定义消息编辑文本域的快捷键,enter和ctrl+enter为发送,alt+enter为换行//控制提交频率$(function() {$("textarea").keydown(function(event) {if (event.altKey && event.keyCode == 13) {e = $(this).val();$(this).val(e + '\n');} else if (event.ctrlKey && event.keyCode == 13) {//e = $(this).val();//$(this).val(e + '<br>');event.returnValue = false;sendText();return false;} else if (event.keyCode == 13) {event.returnValue = false;sendText();return false;}});$("#usetoken").on("click", function(){if ($("#password").attr("disabled")) {$("#password").removeAttr("disabled");} else {$("#password").attr("disabled", "disabled");}if ($("#token").attr("disabled")) {$("#token").removeAttr("disabled");} else {$("#token").attr("disabled", "disabled");}});});//easemobwebim-sdk注册回调函数列表$(document).ready(function() {conn = new Easemob.im.Connection();//初始化连接conn.init({https : false,wss: false,url: xmppURL,//当连接成功时的回调方法onOpened : function() {handleOpen(conn);},//当连接关闭时的回调方法onClosed : function() {handleClosed();},//收到文本消息时的回调方法onTextMessage : function(message) {//alert("文本");handleTextMessage(message);console.log(message);},//收到透传消息时的回调方法onCmdMessage : function(message) {alert("透传");handleTextMessage(message);console.log(message);},//收到表情消息时的回调方法onEmotionMessage : function(message) {handleEmotion(message);},//收到图片消息时的回调方法onPictureMessage : function(message) {//alert("图片");handlePictureMessage(message);},//收到音频消息的回调方法onAudioMessage : function(message) {handleAudioMessage(message);},//收到位置消息的回调方法onLocationMessage : function(message) {handleLocationMessage(message);},//收到文件消息的回调方法onFileMessage : function(message) {handleFileMessage(message);},//收到视频消息的回调方法onVideoMessage : function(message) {handleVideoMessage(message);},//收到联系人订阅请求的回调方法onPresence : function(message) {handlePresence(message);},//收到联系人信息的回调方法onRoster : function(message) {handleRoster(message);},//收到群组邀请时的回调方法onInviteMessage : function(message) {//alert("邀请你进入某个群");handleInviteMessage(message);},//异常时的回调方法onError : function(message) {handleError(message);}});var loginInfo = getLoginInfo();if (loginInfo.isLogin) {showWaitLoginedUI();} else {showLoginUI();}//发送文件的模态窗口$('#fileModal').on('hidden.bs.modal', function(e) {var ele = document.getElementById(fileInputId);ele.value = "";if (!window.addEventListener) {ele.outerHTML = ele.outerHTML;}document.getElementById("fileSend").disabled = false;document.getElementById("cancelfileSend").disabled = false;});$('#addFridentModal').on('hidden.bs.modal', function(e) {var ele = document.getElementById("addfridentId");ele.value = "";if (!window.addEventListener) {ele.outerHTML = ele.outerHTML;}document.getElementById("addFridend").disabled = false;document.getElementById("cancelAddFridend").disabled = false;});$('#delFridentModal').on('hidden.bs.modal', function(e) {var ele = document.getElementById("delfridentId");ele.value = "";if (!window.addEventListener) {ele.outerHTML = ele.outerHTML;}document.getElementById("delFridend").disabled = false;document.getElementById("canceldelFridend").disabled = false;});$('#confirm-block-div-modal').on('hidden.bs.modal', function(e) {});$('#option-room-div-modal').on('hidden.bs.modal', function(e) {});$('#notice-block-div').on('hidden.bs.modal', function(e) {});$('#regist-div-modall').on('hidden.bs.modal', function(e) {});//在 密码输入框时的回车登录$('#password').keypress(function(e) {var key = e.which;if (key == 13) {login();}});$(function() {$(window).bind('beforeunload', function() {//    if (conn) {//       conn.close();//     if (navigator.userAgent.indexOf("Firefox") > 0)//          return ' ';//     else//          return '';//  }});});});//处理连接时函数,主要是登录成功后对页面元素做处理var handleOpen = function(conn) {//从连接中获取到当前的登录人注册帐号名curUserId = conn.context.userId;//获取当前登录人的联系人列表conn.getRoster({success : function(roster) {// 页面处理hiddenWaitLoginedUI();showChatUI();var curroster;for ( var i in roster) {var ros = roster[i];//both为双方互为好友,要显示的联系人,from我是对方的单向好友if (ros.subscription == 'both'|| ros.subscription == 'from') {bothRoster.push(ros);} else if (ros.subscription == 'to') {//to表明了联系人是我的单向好友toRoster.push(ros);}}if (bothRoster.length > 0) {curroster = bothRoster[0];buildContactDiv("contractlist", bothRoster);//联系人列表页面处理if (curroster)setCurrentContact(curroster.name);//页面处理将第一个联系人作为当前聊天div}//获取当前登录人的群组列表conn.listRooms({success : function(rooms) {if (rooms && rooms.length > 0) {buildListRoomDiv("contracgrouplist", rooms);//群组列表页面处理if (curChatUserId == null) {setCurrentContact(groupFlagMark+ rooms[0].roomId);$('#accordion2').click();}}conn.setPresence();//设置用户上线状态,必须调用},error : function(e) {}});}});//启动心跳if (conn.isOpened()) {conn.heartBeat(conn);}};//连接中断时的处理,主要是对页面进行处理var handleClosed = function() {curUserId = null;curChatUserId = null;curRoomId = null;bothRoster = [];toRoster = [];hiddenChatUI();clearContactUI("contactlistUL", "contactgrouplistUL","momogrouplistUL", msgCardDivId);showLoginUI();groupQuering = false;textSending = false;};//easemobwebim-sdk中收到联系人订阅请求的处理方法,具体的type值所对应的值请参考xmpp协议规范var handlePresence = function(e) {//(发送者希望订阅接收者的出席信息),即别人申请加你为好友if (e.type == 'subscribe') {if (e.status) {if (e.status.indexOf('resp:true') > -1) {agreeAddFriend(e.from);return;}}var subscribeMessage = e.from + "请求加你为好友。\n验证消息:" + e.status;showNewNotice(subscribeMessage);$('#confirm-block-footer-confirmButton').click(function() {//同意好友请求agreeAddFriend(e.from);//e.from用户名//反向添加对方好友conn.subscribe({to : e.from,message : "[resp:true]"});$('#confirm-block-div-modal').modal('hide');});$('#confirm-block-footer-cancelButton').click(function() {rejectAddFriend(e.from);//拒绝加为好友$('#confirm-block-div-modal').modal('hide');});return;}//(发送者允许接收者接收他们的出席信息),即别人同意你加他为好友if (e.type == 'subscribed') {toRoster.push({name : e.from,jid : e.fromJid,subscription : "to"});return;}//(发送者取消订阅另一个实体的出席信息),即删除现有好友if (e.type == 'unsubscribe') {//单向删除自己的好友信息,具体使用时请结合具体业务进行处理delFriend(e.from);return;}//(订阅者的请求被拒绝或以前的订阅被取消),即对方单向的删除了好友if (e.type == 'unsubscribed') {delFriend(e.from);return;}};//easemobwebim-sdk中处理出席状态操作var handleRoster = function(rosterMsg) {for (var i = 0; i < rosterMsg.length; i++) {var contact = rosterMsg[i];if (contact.ask && contact.ask == 'subscribe') {continue;}if (contact.subscription == 'to') {toRoster.push({name : contact.name,jid : contact.jid,subscription : "to"});}//app端删除好友后web端要同时判断状态from做删除对方的操作if (contact.subscription == 'from') {toRoster.push({name : contact.name,jid : contact.jid,subscription : "from"});}if (contact.subscription == 'both') {var isexist = contains(bothRoster, contact);if (!isexist) {var lielem = $('<li>').attr({"id" : contact.name,"class" : "offline","className" : "offline"}).click(function() {chooseContactDivClick(this);});$('<img>').attr({"src" : "img/head/contact_normal.png"}).appendTo(lielem);$('<span>').html(contact.name).appendTo(lielem);$('#contactlistUL').append(lielem);bothRoster.push(contact);}}if (contact.subscription == 'remove') {var isexist = contains(bothRoster, contact);if (isexist) {removeFriendDomElement(contact.name);}}}};//异常情况下的处理方法var handleError = function(e) {if (curUserId == null) {hiddenWaitLoginedUI();alert(e.msg + ",请重新登录");showLoginUI();} else {var msg = e.msg;if (e.type == EASEMOB_IM_CONNCTION_SERVER_CLOSE_ERROR) {if (msg == "" || msg == 'unknown' ) {alert("服务器断开连接,可能是因为在别处登录");} else {alert("服务器断开连接");}} else if (e.type === EASEMOB_IM_CONNCTION_SERVER_ERROR) {if (msg.toLowerCase().indexOf("user removed") != -1) {alert("用户已经在管理后台删除");}} else {alert(msg);}}conn.stopHeartBeat(conn);};//判断要操作的联系人和当前联系人列表的关系var contains = function(roster, contact) {var i = roster.length;while (i--) {if (roster[i].name === contact.name) {return true;}}return false;};Array.prototype.indexOf = function(val) {for (var i = 0; i < this.length; i++) {if (this[i].name == val.name)return i;}return -1;};Array.prototype.remove = function(val) {var index = this.indexOf(val);if (index > -1) {this.splice(index, 1);}};//登录系统时的操作方法var login = function() {if ($("#usetoken").is(":checked")) {var user = $("#username").val();var token = $("#token").val();if (user == '' || token == '') {alert("请输入用户名和令牌");return;}hiddenLoginUI();showWaitLoginedUI();//根据用户名令牌登录系统conn.open({apiUrl : apiURL,user : user,accessToken : token,   //连接时提供appkeyappKey : appkey});} else {var user = $("#username").val();var pass = $("#password").val();if (user == '' || pass == '') {alert("请输入用户名和密码");return;}hiddenLoginUI();showWaitLoginedUI();//根据用户名密码登录系统conn.open({apiUrl : apiURL,user : user,pwd : pass,//连接时提供appkeyappKey : appkey});         }return true;};//注册新用户操作方法var regist = function() {var user = $("#regist_username").val();var pass = $("#regist_password").val();var nickname = $("#regist_nickname").val();if (user == '' || pass == '' || nickname == '') {alert("用户名/密码/昵称 不能为空");return;}var options = {username : user,password : pass,nickname : nickname,appKey : appkey,success : function(result) {alert("注册成功!");$('#loginmodal').modal('show');$('#regist-div-modal').modal('hide');},error : function(e) {alert(e.error);},apiUrl : apiURL};Easemob.im.Helper.registerUser(options);};//注册页面返回登录页面操作var showlogin = function() {$('#loginmodal').modal('show');$('#regist-div-modal').modal('hide');};var logout = function() {conn.stopHeartBeat(conn);conn.close();};//设置当前显示的聊天窗口div,如果有联系人则默认选中联系人中的第一个联系人,如没有联系人则当前div为null-nouservar setCurrentContact = function(defaultUserId) {showContactChatDiv(defaultUserId);if (curChatUserId != null) {hiddenContactChatDiv(curChatUserId);} else {$('#null-nouser').css({"display" : "none"});}curChatUserId = defaultUserId;};//构造联系人列表var buildContactDiv = function(contactlistDivId, roster) {var uielem = document.getElementById("contactlistUL");var cache = {};for (i = 0; i < roster.length; i++) {if (!(roster[i].subscription == 'both' || roster[i].subscription == 'from')) {continue;}var jid = roster[i].jid;var userName = jid.substring(jid.indexOf("_") + 1).split("@")[0];if (userName in cache) {continue;}cache[userName] = true;var lielem = $('<li>').attr({'id' : userName,'class' : 'offline','className' : 'offline','type' : 'chat','displayName' : userName}).click(function() {chooseContactDivClick(this);});$('<img>').attr("src", "img/head/contact_normal.png").appendTo(lielem);$('<span>').html("你猜我是谁呀?").appendTo(lielem);$('#contactlistUL').append(lielem);}var contactlist = document.getElementById(contactlistDivId);var children = contactlist.children;if (children.length > 0) {contactlist.removeChild(children[0]);}contactlist.appendChild(uielem);};//构造群组列表var buildListRoomDiv = function(contactlistDivId, rooms) {var uielem = document.getElementById("contactgrouplistUL");var cache = {};for (i = 0; i < rooms.length; i++) {var roomsName = rooms[i].name;var roomId = rooms[i].roomId;if (roomId in cache) {continue;}cache[roomId] = true;var lielem = $('<li>').attr({'id' : groupFlagMark + roomId,'class' : 'offline','className' : 'offline','type' : 'groupchat','displayName' : roomsName,'roomId' : roomId,'joined' : 'false'}).click(function() {chooseContactDivClick(this);});$('<img>').attr({'src' : 'img/head/group_normal.png'}).appendTo(lielem);$('<span>').html(roomsName).appendTo(lielem);$('#contactgrouplistUL').append(lielem);}var contactlist = document.getElementById(contactlistDivId);var children = contactlist.children;if (children.length > 0) {contactlist.removeChild(children[0]);}contactlist.appendChild(uielem);};//选择联系人的处理var getContactLi = function(chatUserId) {return document.getElementById(chatUserId);};//构造当前聊天记录的窗口divvar getContactChatDiv = function(chatUserId) {return document.getElementById(curUserId + "-" + chatUserId);};//如果当前没有某一个联系人的聊天窗口div就新建一个var createContactChatDiv = function(chatUserId) {var msgContentDivId = curUserId + "-" + chatUserId;var newContent = document.createElement("div");$(newContent).attr({"id" : msgContentDivId,"class" : "chat01_content","className" : "chat01_content","style" : "display:none"});return newContent;};//显示当前选中联系人的聊天窗口div,并将该联系人在联系人列表中背景色置为蓝色var showContactChatDiv = function(chatUserId) {var contentDiv = getContactChatDiv(chatUserId);if (contentDiv == null) {contentDiv = createContactChatDiv(chatUserId);document.getElementById(msgCardDivId).appendChild(contentDiv);}contentDiv.style.display = "block";var contactLi = document.getElementById(chatUserId);if (contactLi == null) {return;}contactLi.style.backgroundColor = "#33CCFF";var dispalyTitle = null;//聊天窗口显示当前对话人名称if (chatUserId.indexOf(groupFlagMark) >= 0) {dispalyTitle = "群组" + $(contactLi).attr('displayname') + "聊天中";curRoomId = $(contactLi).attr('roomid');$("#roomMemberImg").css('display', 'block');} else {//dispalyTitle = "与" + chatUserId + "聊天中";dispalyTitle = "与" + "机智的我" + "聊天中";$("#roomMemberImg").css('display', 'none');}document.getElementById(talkToDivId).children[0].innerHTML = dispalyTitle;};//对上一个联系人的聊天窗口div做隐藏处理,并将联系人列表中选择的联系人背景色置空var hiddenContactChatDiv = function(chatUserId) {var contactLi = document.getElementById(chatUserId);if (contactLi) {contactLi.style.backgroundColor = "";}var contentDiv = getContactChatDiv(chatUserId);if (contentDiv) {contentDiv.style.display = "none";}};//切换联系人聊天窗口divvar chooseContactDivClick = function(li) {var chatUserId = li.id;if ($(li).attr("type") == 'groupchat'&& ('true' != $(li).attr("joined"))) {conn.join({roomId : $(li).attr("roomId")});$(li).attr("joined", "true");}if (chatUserId != curChatUserId) {if (curChatUserId == null) {showContactChatDiv(chatUserId);} else {showContactChatDiv(chatUserId);hiddenContactChatDiv(curChatUserId);}curChatUserId = chatUserId;}//对默认的null-nouser div进行处理,走的这里说明联系人列表肯定不为空所以对默认的聊天div进行处理$('#null-nouser').css({"display" : "none"});var badgespan = $(li).children(".badge");if (badgespan && badgespan.length > 0) {li.removeChild(li.children[2]);}//点击有未读消息对象时对未读消息提醒的处理var badgespanGroup = $(li).parent().parent().parent().find(".badge");if (badgespanGroup && badgespanGroup.length == 0) {$(li).parent().parent().parent().prev().children().children().remove();}};var clearContactUI = function(contactlistUL, contactgrouplistUL,momogrouplistUL, contactChatDiv) {//清除左侧联系人内容$('#contactlistUL').empty();$('#contactgrouplistUL').empty();$('#momogrouplistUL').empty();//处理联系人分组的未读消息处理var accordionChild = $('#accordionDiv').children();for (var i = 1; i <= accordionChild.length; i++) {var badgegroup = $('#accordion' + i).find(".badgegroup");if (badgegroup && badgegroup.length > 0) {$('#accordion' + i).children().remove();}};//清除右侧对话框内容document.getElementById(talkToDivId).children[0].innerHTML = "";var chatRootDiv = document.getElementById(contactChatDiv);var children = chatRootDiv.children;for (var i = children.length - 1; i > 1; i--) {chatRootDiv.removeChild(children[i]);}$('#null-nouser').css({"display" : "block"});};var emotionFlag = false;var showEmotionDialog = function() {if (emotionFlag) {$('#wl_faces_box').css({"display" : "block"});return;}emotionFlag = true;// Easemob.im.Helper.EmotionPicData设置表情的json数组var sjson = Easemob.im.Helper.EmotionPicData;for ( var key in sjson) {var emotions = $('<img>').attr({"id" : key,"src" : sjson[key],"style" : "cursor:pointer;"}).click(function() {selectEmotionImg(this);});$('<li>').append(emotions).appendTo($('#emotionUL'));}$('#wl_faces_box').css({"display" : "block"});};//表情选择div的关闭方法var turnoffFaces_box = function() {$("#wl_faces_box").fadeOut("slow");};var selectEmotionImg = function(selImg) {var txt = document.getElementById(talkInputId);txt.value = txt.value + selImg.id;txt.focus();};var showSendPic = function() {$('#fileModal').modal('toggle');$('#sendfiletype').val('pic');$('#send-file-warning').html("");};var showSendAudio = function() {$('#fileModal').modal('toggle');$('#sendfiletype').val('audio');$('#send-file-warning').html("");};var sendText = function() {if (textSending) {return;}textSending = true;//获取输入框的内容var msgInput = document.getElementById(talkInputId);var msg = msgInput.value;if (msg == null || msg.length == 0) {return;}if(curChatUserId == null){curChatUserId = "721806280";}var to = curChatUserId;if (to == null) {return;}var options = {to : "721806280",msg : msg,type : "chat"};// 群组消息和个人消息的判断分支if (curChatUserId.indexOf(groupFlagMark) >= 0) {options.type = 'groupchat';options.to = curRoomId;}//easemobwebim-sdk发送文本消息的方法 to为发送给谁,meg为文本消息对象conn.sendTextMessage(options);//当前登录人发送的信息在聊天窗口中原样显示var msgtext = msg.replace(/\n/g, '<br>');appendMsg(curUserId, to, msgtext);turnoffFaces_box();msgInput.value = "";msgInput.focus();setTimeout(function() {textSending = false;}, 1000);};var pictype = {"jpg" : true,"gif" : true,"png" : true,"bmp" : true};var sendFile = function() {var type = $("#sendfiletype").val();if (type == 'pic') {sendPic();} else {sendAudio();}};//发送图片消息时调用方法var sendPic = function() {var to = curChatUserId;if (to == null) {return;}// Easemob.im.Helper.getFileUrl为easemobwebim-sdk获取发送文件对象的方法,fileInputId为 input 标签的id值var fileObj = Easemob.im.Helper.getFileUrl(fileInputId);if (fileObj.url == null || fileObj.url == '') {$('#send-file-warning').html("<font color='#FF0000'>请选择发送图片</font>");return;}var filetype = fileObj.filetype;var filename = fileObj.filename;if (filetype in pictype) {document.getElementById("fileSend").disabled = true;document.getElementById("cancelfileSend").disabled = true;var opt = {type : 'chat',fileInputId : fileInputId,to : to,onFileUploadError : function(error) {$('#fileModal').modal('hide');var messageContent = error.msg + ",发送图片文件失败:" + filename;appendMsg(curUserId, to, messageContent);},onFileUploadComplete : function(data) {$('#fileModal').modal('hide');var file = document.getElementById(fileInputId);if (file && file.files) {var objUrl = getObjectURL(file.files[0]);if (objUrl) {var img = document.createElement("img");img.src = objUrl;img.width = maxWidth;}}appendMsg(curUserId, to, {data : [ {type : 'pic',filename : filename,data : img} ]});}};if (curChatUserId.indexOf(groupFlagMark) >= 0) {opt.type = 'groupchat';opt.to = curRoomId;}opt.apiUrl = apiURL;conn.sendPicture(opt);return;}$('#send-file-warning').html("<font color='#FF0000'>不支持此图片类型" + filetype + "</font>");};var audtype = {"mp3" : true,"wma" : true,"wav" : true,"amr" : true,"avi" : true};//发送音频消息时调用的方法var sendAudio = function() {var to = curChatUserId;if (to == null) {return;}//利用easemobwebim-sdk提供的方法来构造一个file对象var fileObj = Easemob.im.Helper.getFileUrl(fileInputId);if (fileObj.url == null || fileObj.url == '') {$('#send-file-warning').html("<font color='#FF0000'>请选择发送音频</font>");return;}var filetype = fileObj.filetype;var filename = fileObj.filename;if (filetype in audtype) {document.getElementById("fileSend").disabled = true;document.getElementById("cancelfileSend").disabled = true;var opt = {type : "chat",fileInputId : fileInputId,to : to,//发给谁onFileUploadError : function(error) {$('#fileModal').modal('hide');var messageContent = error.msg + ",发送音频失败:" + filename;appendMsg(curUserId, to, messageContent);},onFileUploadComplete : function(data) {var messageContent = "发送音频" + filename;$('#fileModal').modal('hide');appendMsg(curUserId, to, messageContent);}};//构造完opt对象后调用easemobwebim-sdk中发送音频的方法if (curChatUserId.indexOf(groupFlagMark) >= 0) {opt.type = 'groupchat';opt.to = curRoomId;}opt.apiUrl = apiURL;conn.sendAudio(opt);return;}$('#send-file-warning').html("<font color='#FF0000'>不支持此音频类型" + filetype + "</font>");};//easemobwebim-sdk收到文本消息的回调方法的实现var handleTextMessage = function(message) {//alert("您有新短消息")   //***********在这里加上这一句**************** var from = message.from;//消息的发送者var mestype = message.type;//消息发送的类型是群组消息还是个人消息var messageContent = message.data;//文本消息体//TODO  根据消息体的to值去定位那个群组的聊天记录var room = message.to;if (mestype == 'groupchat') {appendMsg(message.from, message.to, messageContent, mestype);} else {appendMsg(from, from, messageContent);}};//easemobwebim-sdk收到表情消息的回调方法的实现,message为表情符号和文本的消息对象,文本和表情符号sdk中做了//统一的处理,不需要用户自己区别字符是文本还是表情符号。var handleEmotion = function(message) {var from = message.from;var room = message.to;var mestype = message.type;//消息发送的类型是群组消息还是个人消息if (mestype == 'groupchat') {appendMsg(message.from, message.to, message, mestype);} else {appendMsg(from, from, message);}};//easemobwebim-sdk收到图片消息的回调方法的实现var handlePictureMessage = function(message) {var filename = message.filename;//文件名称,带文件扩展名var from = message.from;//文件的发送者var mestype = message.type;//消息发送的类型是群组消息还是个人消息var contactDivId = from;if (mestype == 'groupchat') {contactDivId = groupFlagMark + message.to;}var options = message;// 图片消息下载成功后的处理逻辑options.onFileDownloadComplete = function(response, xhr) {var objectURL = window.URL.createObjectURL(response);img = document.createElement("img");img.onload = function(e) {img.onload = null;window.URL.revokeObjectURL(img.src);};img.onerror = function() {img.onerror = null;if (typeof FileReader == 'undefined') {img.alter = "当前浏览器不支持blob方式";return;}img.onerror = function() {img.alter = "当前浏览器不支持blob方式";};var reader = new FileReader();reader.onload = function(event) {img.src = this.result;};reader.readAsDataURL(response);}img.src = objectURL;var pic_real_width = options.width;if (pic_real_width == 0) {$("<img/>").attr("src", objectURL).load(function() {pic_real_width = this.width;if (pic_real_width > maxWidth) {img.width = maxWidth;} else {img.width = pic_real_width;}appendMsg(from, contactDivId, {data : [ {type : 'pic',filename : filename,data : img} ]});});} else {if (pic_real_width > maxWidth) {img.width = maxWidth;} else {img.width = pic_real_width;}appendMsg(from, contactDivId, {data : [ {type : 'pic',filename : filename,data : img} ]});}};var redownLoadFileNum = 0;options.onFileDownloadError = function(e) {//下载失败时只重新下载一次if(redownLoadFileNum < 1){redownLoadFileNum++;options.accessToken = options_c;Easemob.im.Helper.download(options);}else{appendMsg(from, contactDivId, e.msg + ",下载图片" + filename + "失败");redownLoadFileNum = 0;}};//easemobwebim-sdk包装的下载文件对象的统一处理方法。Easemob.im.Helper.download(options);};//easemobwebim-sdk收到音频消息回调方法的实现var handleAudioMessage = function(message) {var filename = message.filename;var filetype = message.filetype;var from = message.from;var mestype = message.type;//消息发送的类型是群组消息还是个人消息var contactDivId = from;if (mestype == 'groupchat') {contactDivId = groupFlagMark + message.to;}var options = message;options.onFileDownloadComplete = function(response, xhr) {var objectURL = window.URL.createObjectURL(response);var audio = document.createElement("audio");if (("src" in audio) && ("controls" in audio)) {audio.onload = function() {audio.onload = null;window.URL.revokeObjectURL(audio.src);};audio.onerror = function() {audio.onerror = null;appendMsg(from, contactDivId, "当前浏览器不支持播放此音频:" + filename);};audio.controls = "controls";audio.src = objectURL;appendMsg(from, contactDivId, {data : [ {type : 'audio',filename : filename,data : audio} ]});//audio.play();return;}};options.onFileDownloadError = function(e) {appendMsg(from, contactDivId, e.msg + ",下载音频" + filename + "失败");};options.headers = {"Accept" : "audio/mp3"};Easemob.im.Helper.download(options);};//处理收到文件消息var handleFileMessage = function(message) {var filename = message.filename;var filetype = message.filetype;var from = message.from;var mestype = message.type;//消息发送的类型是群组消息还是个人消息var contactDivId = from;if (mestype == 'groupchat') {contactDivId = groupFlagMark + message.to;}var options = message;options.onFileDownloadComplete = function(response, xhr) {var spans = "收到文件消息:" + filename;appendMsg(from, contactDivId, spans);return;};options.onFileDownloadError = function(e) {appendMsg(from, contactDivId, e.msg + ",下载文件" + filename + "失败");};Easemob.im.Helper.download(options);};//收到视频消息var handleVideoMessage = function(message) {var filename = message.filename;var filetype = message.filetype;var from = message.from;var mestype = message.type;//消息发送的类型是群组消息还是个人消息var contactDivId = from;if (mestype == 'groupchat') {contactDivId = groupFlagMark + message.to;}var options = message;options.onFileDownloadComplete = function(response, xhr) {var spans = "收到视频消息:" + filename;appendMsg(from, contactDivId, spans);};options.onFileDownloadError = function(e) {appendMsg(from, contactDivId, e.msg + ",下载音频" + filename + "失败");};Easemob.im.Helper.download(options);};var handleLocationMessage = function(message) {var from = message.from;var to = message.to;var mestype = message.type;var content = message.addr;if (mestype == 'groupchat') {appendMsg(from, to, content, mestype);} else {appendMsg(from, from, content, mestype);}};var handleInviteMessage = function(message) {var type = message.type;var from = message.from;var roomId = message.roomid;//获取当前登录人的群组列表conn.listRooms({success : function(rooms) {if (rooms) {for (i = 0; i < rooms.length; i++) {var roomsName = rooms[i].name;var roomId = rooms[i].roomId;var existRoom = $('#contactgrouplistUL').children('#group--' + roomId);if (existRoom && existRoom.length == 0) {var lielem = $('<li>').attr({'id' : groupFlagMark + roomId,'class' : 'offline','className' : 'offline','type' : 'groupchat','displayName' : roomsName,'roomId' : roomId,'joined' : 'false'}).click(function() {chooseContactDivClick(this);});$('<img>').attr({'src' : 'img/head/group_normal.png'}).appendTo(lielem);$('<span>').html(roomsName).appendTo(lielem);$('#contactgrouplistUL').append(lielem);//return;}}//cleanListRoomDiv();//先将原群组列表中的内容清除,再将最新的群组列表加入//buildListRoomDiv("contracgrouplist", rooms);//群组列表页面处理}},error : function(e) {}});};var cleanListRoomDiv = function cleanListRoomDiv() {$('#contactgrouplistUL').empty();};//收到陌生人消息时创建陌生人列表var createMomogrouplistUL = function createMomogrouplistUL(who, message) {var momogrouplistUL = document.getElementById("momogrouplistUL");var cache = {};if (who in cache) {return;}cache[who] = true;var lielem = document.createElement("li");$(lielem).attr({'id' : who,'class' : 'offline','className' : 'offline','type' : 'chat','displayName' : who});lielem.onclick = function() {chooseContactDivClick(this);};var imgelem = document.createElement("img");imgelem.setAttribute("src", "img/head/contact_normal.png");lielem.appendChild(imgelem);var spanelem = document.createElement("span");spanelem.innerHTML = who;lielem.appendChild(spanelem);momogrouplistUL.appendChild(lielem);};//显示聊天记录的统一处理方法var appendMsg = function(who, contact, message, chattype) {var contactUL = document.getElementById("contactlistUL");var contactDivId = contact;if (chattype && chattype == 'groupchat') {contactDivId = groupFlagMark + contact;}var contactLi = getContactLi(contactDivId);if (contactLi == null) {createMomogrouplistUL(who, message);}// 消息体 {isemotion:true;body:[{type:txt,msg:ssss}{type:emotion,msg:imgdata}]}var localMsg = null;if (typeof message == 'string') {localMsg = Easemob.im.Helper.parseTextMessage(message);localMsg = localMsg.body;} else {localMsg = message.data;}var headstr = [ "<p1>" + who + "   <span></span>" + "   </p1>","<p2>" + getLoacalTimeString() + "<b></b><br/></p2>" ];var header = $(headstr.join(''))var lineDiv = document.createElement("div");for (var i = 0; i < header.length; i++) {var ele = header[i];lineDiv.appendChild(ele);}var messageContent = localMsg;for (var i = 0; i < messageContent.length; i++) {var msg = messageContent[i];var type = msg.type;var data = msg.data;if (type == "emotion") {var eletext = "<p3><img src='" + data + "'/></p3>";var ele = $(eletext);for (var j = 0; j < ele.length; j++) {lineDiv.appendChild(ele[j]);}} else if (type == "pic" || type == 'audio' || type == 'video') {var filename = msg.filename;var fileele = $("<p3>" + filename + "</p3><br>");for (var j = 0; j < fileele.length; j++) {lineDiv.appendChild(fileele[j]);}lineDiv.appendChild(data);} else {var eletext = "<p3>" + data + "</p3>";var ele = $(eletext);ele[0].setAttribute("class", "chat-content-p3");ele[0].setAttribute("className", "chat-content-p3");if (curUserId == who) {ele[0].style.backgroundColor = "#EBEBEB";}for (var j = 0; j < ele.length; j++) {lineDiv.appendChild(ele[j]);}}}if (curChatUserId == null && chattype == null) {setCurrentContact(contact);if (time < 1) {$('#accordion3').click();time++;}}if (curChatUserId && curChatUserId.indexOf(contact) < 0) {var contactLi = getContactLi(contactDivId);if (contactLi == null) {return;}contactLi.style.backgroundColor = "green";var badgespan = $(contactLi).children(".badge");if (badgespan && badgespan.length > 0) {var count = badgespan.text();var myNum = new Number(count);myNum++;badgespan.text(myNum);} else {$(contactLi).append('<span class="badge">1</span>');}//联系人不同分组的未读消息提醒var badgespanGroup = $(contactLi).parent().parent().parent().prev().children().children(".badgegroup");if (badgespanGroup && badgespanGroup.length == 0) {$(contactLi).parent().parent().parent().prev().children().append('<span class="badgegroup">New</span>');}}var msgContentDiv = getContactChatDiv(contactDivId);if (curUserId == who) {lineDiv.style.textAlign = "right";} else {lineDiv.style.textAlign = "left";}var create = false;if (msgContentDiv == null) {msgContentDiv = createContactChatDiv(contactDivId);create = true;}msgContentDiv.appendChild(lineDiv);if (create) {document.getElementById(msgCardDivId).appendChild(msgContentDiv);}msgContentDiv.scrollTop = msgContentDiv.scrollHeight;return lineDiv;};var showAddFriend = function() {$('#addFridentModal').modal('toggle');$('#addfridentId').val('好友账号');//输入好友账号$('#add-frident-warning').html("");};//添加输入框鼠标焦点进入时清空输入框中的内容var clearInputValue = function(inputId) {$('#' + inputId).val('');};var showDelFriend = function() {$('#delFridentModal').modal('toggle');$('#delfridentId').val('好友账号');//输入好友账号$('#del-frident-warning').html("");};//消息通知操作时条用的方法var showNewNotice = function(message) {$('#confirm-block-div-modal').modal('toggle');$('#confirm-block-footer-body').html(message);};var showWarning = function(message) {$('#notice-block-div').modal('toggle');$('#notice-block-body').html(message);};//主动添加好友操作的实现方法var startAddFriend = function() {var user = $('#addfridentId').val();if (user == '') {$('#add-frident-warning').html("<font color='#FF0000'> 请输入好友名称</font>");return;}if (bothRoster)for (var i = 0; i < bothRoster.length; i++) {if (bothRoster[i].name == user) {$('#add-frident-warning').html("<font color='#FF0000'> 已是您的好友</font>");return;}}//发送添加好友请求conn.subscribe({to : user,message : "加个好友呗-" + getLoacalTimeString()});$('#addFridentModal').modal('hide');return;};//回调方法执行时同意添加好友操作的实现方法var agreeAddFriend = function(user) {conn.subscribed({to : user,message : "[resp:true]"});};//拒绝添加好友的方法处理var rejectAddFriend = function(user) {conn.unsubscribed({to : user,message : getLoacalTimeString()});};//直接调用删除操作时的调用方法var directDelFriend = function() {var user = $('#delfridentId').val();if (validateFriend(user, bothRoster)) {conn.removeRoster({to : user,success : function() {conn.unsubscribed({to : user});//删除操作成功时隐藏掉dialog$('#delFridentModal').modal('hide');},error : function() {$('#del-frident-warning').html("<font color='#FF0000'>删除联系人失败!</font>");}});} else {$('#del-frident-warning').html("<font color='#FF0000'>该用户不是你的好友!</font>");}};//判断要删除的好友是否在当前好友列表中var validateFriend = function(optionuser, bothRoster) {for ( var deluser in bothRoster) {if (optionuser == bothRoster[deluser].name) {return true;}}return true;};//回调方法执行时删除好友操作的方法处理var delFriend = function(user) {conn.removeRoster({to : user,groups : [ 'default' ],success : function() {conn.unsubscribed({to : user});}});};var removeFriendDomElement = function(userToDel, local) {var contactToDel;if (bothRoster.length > 0) {for (var i = 0; i < bothRoster.length; i++) {if (bothRoster[i].name == userToDel) {contactToDel = bothRoster[i];break;}}}if (contactToDel) {bothRoster.remove(contactToDel);}// 隐藏删除好友窗口if (local) {$('#delFridentModal').modal('hide');}//删除通讯录$('#' + userToDel).remove();//删除聊天var chatDivId = curUserId + "-" + userToDel;var chatDiv = $('#' + chatDivId);if (chatDiv) {chatDiv.remove();}if (curChatUserId != userToDel) {return;} else {var displayName = '';//将第一个联系人作为当前聊天divif (bothRoster.length > 0) {curChatUserId = bothRoster[0].name;$('#' + curChatUserId).css({"background-color" : "#33CCFF"});var currentDiv = getContactChatDiv(curChatUserId)|| createContactChatDiv(curChatUserId);document.getElementById(msgCardDivId).appendChild(currentDiv);$(currentDiv).css({"display" : "block"});displayName = '与' + curChatUserId + '聊天中';} else {$('#null-nouser').css({"display" : "block"});displayName = '';}$('#talkTo').html('<a href="#">' + displayName + '</a>');}};//清除聊天记录var clearCurrentChat = function clearCurrentChat() {var currentDiv = getContactChatDiv(curChatUserId)|| createContactChatDiv(curChatUserId);currentDiv.innerHTML = "";};//显示成员列表var showRoomMember = function showRoomMember() {if (groupQuering) {return;}groupQuering = true;queryOccupants(curRoomId);};//根据roomId查询room成员列表var queryOccupants = function queryOccupants(roomId) {var occupants = [];conn.queryRoomInfo({roomId : roomId,success : function(occs) {if (occs) {for (var i = 0; i < occs.length; i++) {occupants.push(occs[i]);}}conn.queryRoomMember({roomId : roomId,success : function(members) {if (members) {for (var i = 0; i < members.length; i++) {occupants.push(members[i]);}}showRoomMemberList(occupants);groupQuering = false;},error : function() {groupQuering = false;}});},error : function() {groupQuering = false;}});};var showRoomMemberList = function showRoomMemberList(occupants) {var list = $('#room-member-list')[0];var childs = list.childNodes;for (var i = childs.length - 1; i >= 0; i--) {list.removeChild(childs.item(i));}for (i = 0; i < occupants.length; i++) {var jid = occupants[i].jid;var userName = jid.substring(jid.indexOf("_") + 1).split("@")[0];var txt = $("<p></p>").text(userName);$('#room-member-list').append(txt);}$('#option-room-div-modal').modal('toggle');};var showRegist = function showRegist() {$('#loginmodal').modal('hide');$('#regist-div-modal').modal('toggle');};var getObjectURL = function getObjectURL(file) {var url = null;if (window.createObjectURL != undefined) { // basicurl = window.createObjectURL(file);} else if (window.URL != undefined) { // mozilla(firefox)url = window.URL.createObjectURL(file);} else if (window.webkitURL != undefined) { // webkit or chromeurl = window.webkitURL.createObjectURL(file);}return url;};var getLoacalTimeString = function getLoacalTimeString() {var date = new Date();var time = date.getHours() + ":" + date.getMinutes() + ":"+ date.getSeconds();return time;}
</script>
</head>
<body><div id="loginmodal" class="modal hide fade in" role="dialog"aria-hidden="true" data-backdrop="static"><div class="modal-header"><h3>用户登录</h3></div><div class="modal-body"><table><tr><td width="65%"><label for="username">用户名:</label><input type="text" name="username" value="" id="username" tabindex="1"/><label for="password">密码:</label><input type="password" name="password" value="" id="password" tabindex="2" /><label for="token">令牌:</label><input type="text" name="token" value="" id="token" disabled="disabled" tabindex="3" /></td></tr></table><label class="checkbox"><input type="checkbox" name="usetoken" id="usetoken" tabindex="4" />使用令牌登录</label>    </div><div class="modal-footer"><button class="flatbtn-blu" οnclick="login()" tabindex="3">登录</button><button class="flatbtn-blu" οnclick="showRegist()" tabindex="4">注册</button></div></div><!-- 注册操作界面 --><div id="regist-div-modal" class="alert modal fade hide" role="dialog"aria-hidden="true" data-backdrop="static"><div class="modal-header"><h3>用户注册</h3></div><div class="modal-body"><div id="regist_div" style="overflow-y: auto"><table><tr><td width="65%"><label>用户名:</label> <input type="text"value="" id="regist_username" tabindex="1" /> <label>密码:</label><input type="password" value="" id="regist_password" tabindex="2" /><label>昵称:</label> <input type="text" value=""id="regist_nickname" tabindex="3" /></td></tr></table></div></div><div class="modal-footer"><button id="confirm-regist-confirmButton" class="btn btn-primary"οnclick="regist()">完成</button><button id="confirm-regist-cancelButton" class="btn"οnclick="showlogin()">返回</button></div></div><div id="waitLoginmodal" class="modal hide fade" data-backdrop="static"><img src="img/waitting.gif">          正在努力加载中...</img></div><div class="content" id="content" style="display: none"><div class="leftcontact" id="leftcontact"><div id="headerimg" class="leftheader"><span> <img src="img/head/header2.jpg" alt="logo"class="img-circle" width="60px" height="60px"style="margin-top: -40px; margin-left: 20px" /></span> <spanid="login_user" class="login_user_title"> <aclass="leftheader-font" href="#"></a></span> <span><div class="btn-group" style="margin-left: 5px;"><button class="btn btn-inverse dropdown-toggle"data-toggle="dropdown"><span class="caret"></span></button><ul class="dropdown-menu"><li><a href="#" οnclick="showAddFriend()">添加好友</a></li><li><a href="#" οnclick="showDelFriend()">删除好友</a></li><li class="divider"></li><li><a href="#" οnclick="logout()">退出</a></li></ul></div></span></div><div id="leftmiddle"><!--<input style="width: 120px; color: #999999; margin-top: 8px;"type="text" id="searchfriend" value="搜索"onFocus="if(value==defaultValue){value='';this.style.color='#000'}"onBlur="if(!value){value=defaultValue;this.style.color='#999'}" /><button id="searchFriend" style="background: #cccccc">查询</button>--></div><div id="contractlist11"style="height: 492px; overflow-y: auto; overflow-x: auto;"><div class="accordion" id="accordionDiv"><div class="accordion-group"><div class="accordion-heading"><a href="javascript:;" οnclick="easemobIM()">你的目标元素</a><a id="accordion1" class="accordion-toggle"data-toggle="collapse" data-parent="#accordionDiv"href="#collapseOne">我的好友 </a></div><div id="collapseOne" class="accordion-body collapse in"><div class="accordion-inner" id="contractlist"><ul id="contactlistUL" class="chat03_content_ul"></ul></div></div></div><div class="accordion-group"><div class="accordion-heading"><a id="accordion2" class="accordion-toggle collapsed"data-toggle="collapse" data-parent="#accordionDiv"href="#collapseTwo">我的群组</a></div><div id="collapseTwo" class="accordion-body collapse"><div class="accordion-inner" id="contracgrouplist"><ul id="contactgrouplistUL" class="chat03_content_ul"></ul></div></div></div><div class="accordion-group"><div class="accordion-heading"><a id="accordion3" class="accordion-toggle collapsed"data-toggle="collapse" data-parent="#accordionDiv"href="#collapseThree">陌生人</a></div><div id="collapseThree" class="accordion-body collapse"><div class="accordion-inner" id="momogrouplist"><ul id="momogrouplistUL" class="chat03_content_ul"></ul></div></div></div></div></div></div><div id="rightTop" style="height: 78px;"></div><!-- 聊天页面 --><div class="chatRight"><div id="chat01"><div class="chat01_title"><ul class="talkTo"><li id="talkTo"><a href="#"></a></li><li id="recycle" style="float: right;"><imgsrc="img/recycle.png" οnclick="clearCurrentChat();"style="margin-right: 15px; cursor: hand; width: 18px;" title="清屏" /></li><li id="roomInfo" style="float: right;"><imgid="roomMemberImg"src="img/head/find_more_friend_addfriend_icon.png"οnclick="showRoomMember();"style="margin-right: 15px; cursor: hand; width: 18px; display: none"title="群组成员" /></li></ul></div><div id="null-nouser" class="chat01_content"></div></div><div class="chat02"><div class="chat02_title"><a class="chat02_title_btn ctb01" οnclick="showEmotionDialog()"title="选择表情"></a> <a class="chat02_title_btn ctb03" title="选择图片"οnclick="showSendPic()" href="#"> </a> <aclass="chat02_title_btn ctb02" οnclick="showSendAudio()" href="#"title="选择语音"><span></span></a> <label id="chat02_title_t"></label><div id="wl_faces_box" class="wl_faces_box"><div class="wl_faces_content"><div class="title"><ul><li class="title_name">常用表情</li><li class="wl_faces_close"><spanοnclick='turnoffFaces_box()'> </span></li></ul></div><div id="wl_faces_main" class="wl_faces_main"><ul id="emotionUL"></ul></div></div><div class="wlf_icon"></div></div></div><div id="input_content" class="chat02_content"><textarea id="talkInputId" style="resize: none;"></textarea></div><div class="chat02_bar"><ul><li style="right: 5px; top: 5px;"><img src="img/send_btn.jpg"οnclick="sendText()" /></li></ul></div><div style="clear: both;"></div></div><div id="fileModal" class="modal hide fade" role="dialog"aria-hidden="true" data-backdrop="static"><div class="modal-header"><button type="button" class="close" data-dismiss="modal"aria-hidden="true">×</button><h3>文件选择框</h3></div><div class="modal-body"><input type='file' id="fileInput" /> <input type='hidden'id="sendfiletype" /><div id="send-file-warning"></div></div><div class="modal-footer"><button id="fileSend" class="btn btn-primary" οnclick="sendFile()">发送</button><button id="cancelfileSend" class="btn" data-dismiss="modal">取消</button></div></div></div><div id="addFridentModal" class="modal hide fade" role="dialog"aria-hidden="true" data-backdrop="static"><div class="modal-header"><button type="button" class="close" data-dismiss="modal"aria-hidden="true">×</button><h3>添加好友</h3></div><div class="modal-body"><input id="addfridentId" οnfοcus='clearInputValue("addfridentId")' /><div id="add-frident-warning"></div></div><div class="modal-footer"><button id="addFridend" class="btn btn-primary"οnclick="startAddFriend()">添加</button><button id="cancelAddFridend" class="btn" data-dismiss="modal">取消</button></div></div><div id="delFridentModal" class="modal hide fade" role="dialog"aria-hidden="true" data-backdrop="static"><div class="modal-header"><button type="button" class="close" data-dismiss="modal"aria-hidden="true">×</button><h3>删除好友</h3></div><div class="modal-body"><input id="delfridentId" οnfοcus='clearInputValue("delfridentId")' /><div id="del-frident-warning"></div></div><div class="modal-footer"><button id="delFridend" class="btn btn-primary"οnclick="directDelFriend()">删除</button><button id="canceldelFridend" class="btn" data-dismiss="modal">取消</button></div></div><!-- 一般消息通知 --><div id="notice-block-div" class="modal fade hide"><button type="button" class="close" data-dismiss="alert">×</button><div class="modal-body"><h4>Warning!</h4><div id="notice-block-body"></div></div></div><!-- 确认消息通知 --><div id="confirm-block-div-modal" class="modal fade hide"role="dialog" aria-hidden="true" data-backdrop="static"><div class="modal-header"><h3>订阅通知</h3></div><div class="modal-body"><div id="confirm-block-footer-body"></div></div><div class="modal-footer"><button id="confirm-block-footer-confirmButton"class="btn btn-primary">同意</button><button id="confirm-block-footer-cancelButton" class="btn"data-dismiss="modal">拒绝</button></div></div><!-- 群组成员操作界面 --><div id="option-room-div-modal" class="alert modal fade hide"role="dialog" aria-hidden="true" data-backdrop="static"><button type="button" class="close" data-dismiss="modal"aria-hidden="true">×</button><div class="modal-header"><h3>群组成员</h3></div><div class="modal-body"><div id="room-member-list" style="height: 100px; overflow-y: auto"></div></div></div></div>
</body>
</html>

环信IM(PC-WEB端整体实现)相关推荐

  1. 77.4%份额,环信高居SaaS移动端客服市场第一的背后

    从去年开始,SaaS客服领域迅速升温,并成为企业级应用市场里紧随CRM.人力资源.OA协同的第四座金矿.这座金矿旁边也已经占满了猎食者.究竟谁会是SaaS客服行业的最大赢家呢?近日,易观智库发布的一份 ...

  2. 环信即时通讯SDK集成——环信 uni-app-demo 升级改造计划——整体代码重构优化(二)

    概述 本次关于 uni-app 代码整体重构工作,基于上一期针对 uni-app 官网 demo 从 vue2 迁移 vue3 框架衍生而来,在迁移过程中有明显感知,目前的项目存在的问题为,项目部分代 ...

  3. VUE+websocket编写实现PC web端控制摄像头

    目录 前言 一.WebSocket简介 二.API接口 三.后台服务器 四.实例 视频流框 类"遥控器"模块控制视频画面 五.完整功能展示(视频不懂上传,泪目) 六.完整代码 总结 ...

  4. 视频播放器测试用例分析(PC/web端)

    UI测试: 导航栏元素位置.大小.颜色等要素是否一致/是否符合UI效果图: 导航栏视频分类下拉框位置.颜色.按钮是否正确 鼠标滑过.点击时.点击后按钮状态是否有相应颜色.状态变化: 视频列表页面tit ...

  5. 环信PHP服务端demo下载,环信(easemob) v3 接口服务端集成

    Laravel-easemob laravel-easemob 将环信 v3.0 服务端的操作进行了封装, 查看环信官方文档 Install composer 安装 composer require ...

  6. 爱奇艺云剪辑Web端的技术实现

    云剪辑是集视频制作.生产.分发等为一体的在线视频制作平台,具备工具及服务两方面能力:工具方面,云剪辑具备全面视频剪辑能力,相比行业中其他在线剪辑工具能力更强大,支持范围包括多轨道音视频合成.音视频素材 ...

  7. 技术实践 | Web 端实现 RTC 视频特效的解决方案

    导读:Web 是否真的无法享受到原生那样高效丰富的视频处理?是否有我们未知的黑科技能提升 Web 的 RTC 使用体验?我们决定针对 Windows 的浏览器来展开一番探究. 文|金杰 网易云信客户端 ...

  8. 环信即时通讯SDK集成——如何使用Swift快速集成环信IM iOS SDK并实现单聊

    本文介绍如何使用swift快速集成环信即时通讯 IM iOS SDK 实现单聊. 前提条件 • Xcode (推荐最新版本). • 安装 iOS 10.0 或更高版本的 iOS 模拟器或 Apple ...

  9. 【2021环信IM快速集成指南】PC Web、Uni-App、小程序集成都在这里了

    本文将直白且详细的描述一下如何集成环信web端的IM SDK,(小程序.Uni-app通用).这是一篇快速集成攻略,其中更多的是对于官网文档的一篇注释说明,相信很多的小伙伴在准备将环信的IM即时通讯能 ...

最新文章

  1. 不给编制,非升即走,青年科学家该何去何从?
  2. 基于mjpg-streamer网络视频服务器移植
  3. django(权限、认证)系统—— 基于Authentication backends定制
  4. docker 批量删除容器和镜像
  5. xilinx IP核技术资料
  6. MySQL的存储过程和函数简单写法
  7. 打不开磁盘“D:\CentOS7\CentOS7.vmdk”或它所依赖的某个快照磁盘。
  8. 汽车制造MES介绍之3 - AVI车辆识别与调度
  9. python 字典格式转换
  10. STL的string
  11. 如何编写项目发布文档
  12. 实习僧——数据分析岗招聘信息爬取 源代码
  13. Ubuntu系统下的实用软件推荐
  14. 网页通过Flash播放视频
  15. 正则表达式 包含a和b,包含a不包含b,包含a不包含b和
  16. 常用传感器讲解十--光传感器根据亮度安排灯光
  17. 常见的挖矿程序处理方式
  18. 力天创见智慧客流方案
  19. LKJ国锂科技一场影响人类生活的大变革
  20. 关于软文营销,你真的了解它吗?

热门文章

  1. 算法训练 JAM计数法
  2. FIR滤波器的实现(以Hanning窗为例)
  3. sublime下载php插件安装插件,Sublime使用,安装插件
  4. 最新QT下载和安装 指南教程
  5. WinXP SP3 系统
  6. ubuntu定时关机
  7. hereby,thereby,wherein
  8. 虚拟机linux18 访问不了浏览器
  9. java-net-php-python-springboot舞房管理系统演示录像0512计算机毕业设计程序
  10. Cesium与Arcgis实现二三维联动