环信IM(PC-WEB端整体实现)
主搞后端开发,前端技术不是很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端整体实现)相关推荐
- 77.4%份额,环信高居SaaS移动端客服市场第一的背后
从去年开始,SaaS客服领域迅速升温,并成为企业级应用市场里紧随CRM.人力资源.OA协同的第四座金矿.这座金矿旁边也已经占满了猎食者.究竟谁会是SaaS客服行业的最大赢家呢?近日,易观智库发布的一份 ...
- 环信即时通讯SDK集成——环信 uni-app-demo 升级改造计划——整体代码重构优化(二)
概述 本次关于 uni-app 代码整体重构工作,基于上一期针对 uni-app 官网 demo 从 vue2 迁移 vue3 框架衍生而来,在迁移过程中有明显感知,目前的项目存在的问题为,项目部分代 ...
- VUE+websocket编写实现PC web端控制摄像头
目录 前言 一.WebSocket简介 二.API接口 三.后台服务器 四.实例 视频流框 类"遥控器"模块控制视频画面 五.完整功能展示(视频不懂上传,泪目) 六.完整代码 总结 ...
- 视频播放器测试用例分析(PC/web端)
UI测试: 导航栏元素位置.大小.颜色等要素是否一致/是否符合UI效果图: 导航栏视频分类下拉框位置.颜色.按钮是否正确 鼠标滑过.点击时.点击后按钮状态是否有相应颜色.状态变化: 视频列表页面tit ...
- 环信PHP服务端demo下载,环信(easemob) v3 接口服务端集成
Laravel-easemob laravel-easemob 将环信 v3.0 服务端的操作进行了封装, 查看环信官方文档 Install composer 安装 composer require ...
- 爱奇艺云剪辑Web端的技术实现
云剪辑是集视频制作.生产.分发等为一体的在线视频制作平台,具备工具及服务两方面能力:工具方面,云剪辑具备全面视频剪辑能力,相比行业中其他在线剪辑工具能力更强大,支持范围包括多轨道音视频合成.音视频素材 ...
- 技术实践 | Web 端实现 RTC 视频特效的解决方案
导读:Web 是否真的无法享受到原生那样高效丰富的视频处理?是否有我们未知的黑科技能提升 Web 的 RTC 使用体验?我们决定针对 Windows 的浏览器来展开一番探究. 文|金杰 网易云信客户端 ...
- 环信即时通讯SDK集成——如何使用Swift快速集成环信IM iOS SDK并实现单聊
本文介绍如何使用swift快速集成环信即时通讯 IM iOS SDK 实现单聊. 前提条件 • Xcode (推荐最新版本). • 安装 iOS 10.0 或更高版本的 iOS 模拟器或 Apple ...
- 【2021环信IM快速集成指南】PC Web、Uni-App、小程序集成都在这里了
本文将直白且详细的描述一下如何集成环信web端的IM SDK,(小程序.Uni-app通用).这是一篇快速集成攻略,其中更多的是对于官网文档的一篇注释说明,相信很多的小伙伴在准备将环信的IM即时通讯能 ...
最新文章
- 不给编制,非升即走,青年科学家该何去何从?
- 基于mjpg-streamer网络视频服务器移植
- django(权限、认证)系统—— 基于Authentication backends定制
- docker 批量删除容器和镜像
- xilinx IP核技术资料
- MySQL的存储过程和函数简单写法
- 打不开磁盘“D:\CentOS7\CentOS7.vmdk”或它所依赖的某个快照磁盘。
- 汽车制造MES介绍之3 - AVI车辆识别与调度
- python 字典格式转换
- STL的string
- 如何编写项目发布文档
- 实习僧——数据分析岗招聘信息爬取 源代码
- Ubuntu系统下的实用软件推荐
- 网页通过Flash播放视频
- 正则表达式 包含a和b,包含a不包含b,包含a不包含b和
- 常用传感器讲解十--光传感器根据亮度安排灯光
- 常见的挖矿程序处理方式
- 力天创见智慧客流方案
- LKJ国锂科技一场影响人类生活的大变革
- 关于软文营销,你真的了解它吗?