千家信息网

怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序

发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,这篇文章主要讲解了"怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用Ja
千家信息网最后更新 2025年01月17日怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序

这篇文章主要讲解了"怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序"吧!

此程序可以和所有连接到Openfire服务器的应用进行通信、发送消息。如果要运行本程序还需要一个聊天服务器Openfire,

以及需要用到Http方式和Openfire通信的第三方库(JabberHTTPBind)。

JabberHTTPBind是jabber提供的XMPP协议通信的Http bind发送的形式,它可以完成WebBrowser和Openfire建立长连接通信。

可以发送表情、改变字体样式(对方界面也可以看到你的字体样式),同时右侧是显示/收缩详情的信息

收缩详情

聊天界面部分截图

用户登录、注册,sendTo表示你登录后向谁发送聊天消息、并且建立一个聊天窗口

登录成功后,你可以在日志控制台看到你的登陆状态、或是在firebug控制台中看到你的连接请求状态

登陆失败

只有connecting,就没有下文了

登陆成功后,你就可以给指定用户发送消息,且设置你想发送消息的新用户点击new Chat按钮创建新会话

如果你来了新消息,在浏览器的标题栏会有新消息提示

如果你当前聊天界面的窗口都是关闭状态,那么在右下角会有消息提示的闪动图标

开发环境

System:Windows

JavaEE Server:Tomcat 5.0.28+/Tomcat 6

WebBrowser:IE6+、Firefox3.5+、Chrome 已经兼容浏览器

JavaSDK:JDK 1.6+

Openfire 3.7.1

IDE:eclipse 3.2、MyEclipse 6.5

开发依赖库

jdk1.4+

serializer.jar

xalan.jar

jhb-1.0.jar

log4j-1.2.16.jar

jhb-1.0.jar 这个就是JabberHTTPBind,我把编译的class打成jar包了

JavaScript lib

jquery.easydrag.js 窗口拖拽JavaScript lib

jquery-1.7.1.min.js jquery lib

jsjac.js 通信核心库

local.chat-2.0.js 本地会话窗口发送消息JavaScript库

remote.jsjac.chat-2.0.js 远程会话消息JavaScript库

send.message.editor-1.0.js 窗口编辑器JavaScript库

一、准备工作

jsjac JavaScript lib下载:https://github.com/sstrigler/JSJaC/

如果你不喜欢用jsjac JavaScript lib和Openfire通信,那么有一款jQuery的plugin可以供你使用,下载地址

jQuery-XMPP-plugin https://github.com/maxpowel/jQuery-XMPP-plugin

这里有所以能支持Openfire通信的第三方库,有兴趣的可以研究下 http://xmpp.org/xmpp-software/libraries/

jquery.easydrag 下载:http://fromvega.com/code/easydrag/jquery.easydrag.js

jquery 下载:http://code.jquery.com/jquery-1.7.1.min.js

JabberHTTPBind jhb.jar 下载:http://download.csdn.net/detail/ibm_hoojo/4489188

images 图片素材:http://download.csdn.net/detail/ibm_hoojo/4489439

工程目录结构

二、核心代码演示

1、主界面(登陆、消息提示、日志、建立新聊天窗口)代码 index.jsp

<%@ page language="java" pageEncoding="UTF-8" %> <%  String path = request.getContextPath();  String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  %>                        WebIM Chat                                                                                                              
userName: password: register: sendTo:

下面这段代码尤为重要,它是设置你链接openfire的地址。这个地址一段错误你将无法进行通信!

$.WebIM方法是主函数,用它可以覆盖local.chat中的基本配置,它可以完成聊天窗口的创建。$.WebIM.newWebIM方法是新创建一个窗口,只是消息的接收者是一个新用户。

$.WebIM({      sender: userName,      receiver: receiver  });     $.WebIM.newWebIM({      receiver: receiver  });

remote.jsjac.chat.login(document.userForm);方法是用户登录到Openfire服务器

参数如下:

httpbase: window.contextPath + "/JHB/", //请求后台http-bind服务器url  domain: window["serverDomin"], //"192.168.5.231", // 192.168.5.231 当前有效域名  username: "", // 登录用户名  pass: "", // 密码  timerval: 2000, // 设置请求超时  resource: "WebIM", // 链接资源标识  register: true // 是否注册

remote.jsjac.chat.logout();是退出、断开openfire的链接

2、本地聊天应用核心代码 local.chat-2.0.js

/***   * jquery local chat   * @version v2.0    * @createDate -- 2012-5-28   * @author hoojo   * @email hoojo_@126.com   * @blog http://hoojo.cnblogs.com & http://blog.csdn.net/IBM_hoojo   * @requires jQuery v1.2.3 or later, send.message.editor-1.0.js   * Copyright (c) 2012 M. hoo   **/    ;(function ($) {         if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) {          alert('WebIM requires jQuery v1.2.3 or later!  You are using v' + $.fn.jquery);          return;      }            var faceTimed, count = 0;            var _opts = defaultOptions = {          version: 2.0,          chat: "#chat",          chatEl: function () {              var $chat = _opts.chat;              if ((typeof _opts.chat) == "string") {                  $chat = $(_opts.chat);              } else if ((typeof _opts.chat) == "object") {                  if (!$chat.get(0)) {                      $chat = $($chat);                  }              }               return $chat;          },          sendMessageIFrame: function (receiverId) {              return $("iframe[name='sendMessage" + receiverId + "']").get(0).contentWindow;          },          receiveMessageDoc: function (receiverId) {              receiverId = receiverId || "";              var docs = [];              $.each($("iframe[name^='receiveMessage" + receiverId + "']"), function () {                  docs.push($(this.contentWindow.document));              });              return docs;              //return $($("iframe[name^='receiveMessage" + receiverId + "']").get(0).contentWindow.document);          },          sender: "", // 发送者          receiver: "", // 接收者          setTitle: function (chatEl) {              var receiver = this.getReceiver(chatEl);              chatEl.find(".title").html("和" + receiver + "聊天对话中");          },          getReceiver: function (chatEl) {              var receiver = chatEl.attr("receiver");              if (~receiver.indexOf("@")) {                  receiver = receiver.split("@")[0];              }              return receiver;          },                    // 接收消息iframe样式          receiveStyle: [              '',                  '',                  '',              ''         ].join(""),          writeReceiveStyle: function (receiverId) {              this.receiveMessageDoc(receiverId)[0].get(0).write(this.receiveStyle);          },                    datetimeFormat: function (v) {              if (~~v < 10) {                  return "0" + v;              }              return v;          },          getDatetime: function () {              // 设置当前发送日前              var date = new Date();              var datetime = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate();              datetime = " " + _opts.datetimeFormat(date.getHours())                           + ":" + _opts.datetimeFormat(date.getMinutes())                           + ":" + _opts.datetimeFormat(date.getSeconds());              return datetime;          },                    /***           * 发送消息的格式模板                               * flag = true 表示当前user是自己,否则就是对方           **/           receiveMessageTpl: function (userName, styleTpl, content, flag) {              var userCls = flag ? "me" : "you";              if (styleTpl && flag) {                  content = [ "", content, "" ].join("");              }              return [                  '

', _opts.getDatetime(), ' ', userName, ':

', '

', content, '

' ].join(""); }, // 工具类按钮触发事件返回html模板 sendMessageStyle: { cssStyle: { bold: "font-weight: bold;", underline: "text-decoration: underline;", italic: "font-style: oblique;" }, setStyle: function (style, val) { if (val) { _opts.sendMessageStyle[style] = val; } else { var styleVal = _opts.sendMessageStyle[style]; if (styleVal === undefined || !styleVal) { _opts.sendMessageStyle[style] = true; } else { _opts.sendMessageStyle[style] = false; } } }, getStyleTpl: function () { var tpl = ""; $.each(_opts.sendMessageStyle, function (style, item) { //alert(style + "#" + item + "#" + (typeof item)); if (item === true) { tpl += _opts.sendMessageStyle.cssStyle[style]; } else if ((typeof item) === "string") { //alert(style + "-------------" + sendMessageStyle[style]); tpl += style + ":" + item + ";"; } }); return tpl; } }, // 向接收消息iframe区域写消息 writeReceiveMessage: function (receiverId, userName, content, flag) { if (content) { // 发送消息的样式 var styleTpl = _opts.sendMessageStyle.getStyleTpl(); var receiveMessageDoc = _opts.receiveMessageDoc(receiverId); $.each(receiveMessageDoc, function () { var $body = this.find("body"); // 向接收信息区域写入发送的数据 $body.append(_opts.receiveMessageTpl(userName, styleTpl, content, flag)); // 滚动条滚到底部 this.scrollTop(this.height()); }); } }, // 发送消息 sendHandler: function ($chatMain) { var doc = $chatMain.find("iframe[name^='sendMessage']").get(0).contentWindow.document; var content = doc.body[xss_clean]; content = $.trim(content); content = content.replace(new RegExp("
", "gm"), ""); // 获取即将发送的内容 if (content) { var sender = $chatMain.attr("sender"); var receiverId = $chatMain.attr("id"); // 接收区域写消息 _opts.writeReceiveMessage(receiverId, sender, content, true); //############# XXX var receiver = $chatMain.find("#to").val(); //var receiver = $chatMain.attr("receiver"); // 判断是否是手机端会话,如果是就发送纯text,否则就发送html代码 var flag = _opts.isMobileClient(receiver); if (flag) { var text = $(doc.body).text(); text = $.trim(text); if (text) { // 远程发送消息 remote.jsjac.chat.sendMessage(text, receiver); } } else { // 非手机端通信 可以发送html代码 var styleTpl = _opts.sendMessageStyle.getStyleTpl(); content = [ "", content, "" ].join(""); remote.jsjac.chat.sendMessage(content, receiver); } // 清空发送区域 $(doc).find("body").html(""); } }, faceImagePath: "images/emotions/", faceElTpl: function (i) { return [ "" ].join(""); }, // 创建表情html elements createFaceElement: function ($chat) { var faces = []; for (var i = 1; i < 100; i++) { faces.push(this.faceElTpl(i)); if (i % 11 == 0) { faces.push("
"); } } $chat.find("#face").html(faces.join("")); this.faceHandler($chat); }, // 插入表情 faceHandler: function ($chat) { $chat.find("#face img").click(function () { $chat.find("#face").hide(150); var imgEL = ""; var $chatMain = $(this).parents(".chat-main"); var win = $chatMain.find("iframe[name^='sendMessage']").get(0).contentWindow; var doc = win.document; sendMessageEditor.insertAtCursor(imgEL, doc, win); }); // 表情隐藏 $chat.find("#face, #face img").mouseover(function () { window.clearTimeout(faceTimed); }).mouseout(function () { window.clearTimeout(faceTimed); faceTimed = window.setTimeout(function () { $chat.find("#face").hide(150); }, 700); }); }, /*** * 发送消息工具栏按钮事件方法 **/ toolBarHandler: function () { var $chat = $(this).parents(".chat-main"); var targetCls = $(this).attr("class"); if (targetCls == "face") { $chat.find("#face").show(150); window.clearTimeout(faceTimed); faceTimed = window.setTimeout(function () { $chat.find("#face").hide(150); }, 1000); } else if (this.tagName == "DIV") { _opts.sendMessageStyle.setStyle(targetCls); } else if (this.tagName == "SELECT") { _opts.sendMessageStyle.setStyle($(this).attr("name"), $(this).val()); if ($(this).attr("name") == "color") { $(this).css("background-color", $(this).val()); } } // 设置sendMessage iframe的style css _opts.writeSendStyle(); }, // 设置sendMessage iframe的style css writeSendStyle: function () { var styleTpl = _opts.sendMessageStyle.getStyleTpl(); var styleEL = [''].join(""); $("body").find("iframe[name^='sendMessage']").each(function () { var $head = $(this.contentWindow.document).find("head"); if ($head.find("style").size() > 1) { $head.find("style:gt(0)").remove(); } if (styleTpl) { $head.append(styleEL); } }); }, isMobileClient: function (receiver) { var moblieClients = ["iphone", "ipad", "ipod", "wp7", "android", "blackberry", "Spark", "warning", "symbian"]; var flag = false; for (var i in moblieClients) { if (~receiver.indexOf(moblieClients[i])) { return true; } } return false; }, // 聊天界面html元素 chatLayoutTemplate: function (userJID, sender, receiver, product, flag) { var display = ""; if (flag) { display = "style='display: none;'"; } return [ '
', '
', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '
', '', '', '
    ', '
    商品详情
    ', '
  • ', '
  • ', '
  • ', product.name, '
  • ', '
  • 团购价:', product.price, '
  • ', '
  • 市场价:', product.marketPrice, '
  • ', '
  • 快递公司:', product.deliverOrgs, '
  • ', '
  • 仓库:', product.wareHouses, '
  • ', product.skuAttrs, '
', '
', '', '', '', '
', '
', '
', '
', '
消息记录
', '
', '', '
', '
', '
', '
', '
' ].join(""); }, initWebIM: function (userJID, receiver) { var product = { name: "小玩熊", pic: "http://avatar.csdn.net/9/7/A/2_ibm_hoojo.jpg", price: "198.00", marketPrice: "899.90", deliverOrgs: "EMS", wareHouses: "A库", skuAttrs: "" }; var chatEl = $(_opts.chatLayoutTemplate(userJID, _opts.sender, receiver, product)); $("body").append(chatEl); // 拖拽 $("#" + userJID).easydrag(); // 初始化sendMessageEditor相关信息 sendMessageEditor.iframe = this.sendMessageIFrame(userJID); sendMessageEditor.init(userJID); _opts.setTitle(chatEl); _opts.writeReceiveStyle(userJID); _opts.writeSendStyle(); _opts.createFaceElement(chatEl); // 查看更多详情 chatEl.find(".more").click(function () { var $ul = $(this).parents("ul"); $ul.find(".more").toggle(); $ul.find(".info").toggle(); $ul.find(".pic").toggle(); }); // 收缩详情 chatEl.find(".split").toggle(function () { $(".product-info").hide(); $(this).parents(".radius").css("border-right-width", "0"); }, function () { $(".product-info").show(); $(this).parents(".radius").css("border-right-width", "8px"); }); // 工具类绑定事件 settings.toolBarHandler chatEl.find(".tool-bar td").children().click(this.toolBarHandler); chatEl.find("#send").click(function () { var $chatMain = $(this).parents(".chat-main"); _opts.sendHandler($chatMain); }); chatEl.find("#close").click(function () { var $chatMain = $(this).parents(".chat-main"); $chatMain.hide(500); }); // 首先取消事件绑定,当一次性发多条消息的情况下会同时绑定多个相同事件 $(".have-msg, .no-msg, .chat-main").unbind("click"); $(".have-msg").bind("click", function () { $(this).hide(); $(".no-msg").show(); $(".chat-main:hidden").show(150); }); $(".no-msg").click(function () { $(".chat-main:hidden").each(function (i, item) { var top = i * 10 + 50; var left = i * 20 + 50; $(this).show(500).css({top: top, left: left}); }); }); $(".chat-main").click(function () { $(".chat-main").css("z-index", 9999); $(this).css({"z-index": 10000}); }); $(this.sendMessageIFrame(userJID).document).keyup(function (event) { var e = event || window.event; var keyCode = e.which || e.keyCode; if (keyCode == 13) { var $chatMain = $("#" + $(this).find("body").attr("jid")); _opts.sendHandler($chatMain); } }); }, // 建立新聊天窗口 newWebIM: function (settings) { var chatUser = remote.userAddress(settings.receiver); var userJID = "u" + hex_md5(chatUser); _opts.initWebIM(userJID, chatUser); $("#" + userJID).find(remote.receiver).val(chatUser); $("#" + userJID).show(220); }, // 远程发送消息时执行函数 messageHandler: function (user, content) { var userName = user.split("@")[0]; var tempUser = user; if (~tempUser.indexOf("/")) { tempUser = tempUser.substr(0, tempUser.indexOf("/")); } var userJID = "u" + hex_md5(tempUser); // ***初始webIM if (!$("#" + userJID).get(0)) { // 初始IM面板; _opts.initWebIM(userJID, user); } // 设置消息接受者的名称 $("#" + userJID).find(remote.receiver).val(user); if ($("#" + userJID).get(0)) { // 消息提示 if ($("div[id='" + userJID + "']:hidden").get(0)) { var haveMessage = $(".have-msg"); haveMessage.show(); $(".no-msg").hide(); } _opts.messageTip("闪聊有了新消息,请查收!"); // 向chat接收信息区域写消息 remote.jsjac.chat.writeMessage(userJID, userName, content); } }, // 消息提示 messageTip: function () { if (count % 2 == 0) { window.focus(); document.title = "你来了新消息,请查收!"; } else { document.title = ""; } if (count > 4) { document.title = ""; count = 0; } else { window.setTimeout(_opts.messageTip, 1000); count ++; } } }; // 初始化远程聊天程序相关方法 var initRemoteIM = function (settings) { // 初始化远程消息 remote.jsjac.chat.init(); // 设置客户端写入信息方法 remote.jsjac.chat.writeReceiveMessage = settings.writeReceiveMessage; // 注册事件 $(window).bind({ unload: remote.jsjac.chat.unloadHandler, error: remote.jsjac.chat.errorHandler, beforeunload: remote.jsjac.chat.logout }); } $.extend({ WebIM: function (opts) { opts = opts || {}; // 覆盖默认配置 defaultOptions = $.extend(defaultOptions, defaultOptions, opts); var settings = $.extend({}, defaultOptions, opts); initRemoteIM(settings); settings.newWebIM(settings); $.WebIM.settings = settings; } }); $.WebIM.settings = $.WebIM.settings || _opts; $.WebIM.initWebIM = _opts.initWebIM; $.WebIM.newWebIM = _opts.newWebIM; $.WebIM.messageHandler = _opts.messageHandler; })(jQuery);

这里的方法基本上是聊天窗口上的应用,主要是本地聊天程序的js、HTML元素的操作。如字体、字体大小、颜色、表情、消息的发送等,不涉及到聊天消息发送的核心代码,其中有用到发送远程消息的方法。

remote.jsjac.chat.sendMessage(text, receiver); 这个是发送远程消息的方法,参数1是消息内容、参数2是消息的接收者

如果你有看到这篇文章http://www.cnblogs.com/hoojo/archive/2012/06/18/2553886.html 它是一个单纯的WebIM本地的聊天界面。

3、远程聊天JavaScript核心代码,它是和jsjac库关联的。

remote.jsjac.chat-2.0.js

/**   * IM chat jsjac remote message   * @author: hoojo   * @email: hoojo_@126.com   * @blog http://hoojo.cnblogs.com & http://blog.csdn.net/IBM_hoojo   * @createDate: 2012-5-24   * @version 2.0   * @requires jQuery v1.2.3 or later   * Copyright (c) 2012 M. hoo   **/    var remote = {      debug: "info, error",      chat: "body",      receiver: "#to", // 接受者jquery expression      console: {          errorEL: function () {              if ($(remote.chat).get(0)) {                  return $(remote.chat).find("#error");              } else {                  return $("body").find("#error");              }          },          infoEL: function () {              if ($(remote.chat).get(0)) {                  return $(remote.chat).find("#info");              } else {                  return $("body").find("#info");              }          },          // debug info          info: function (html) {              if (~remote.debug.indexOf("info")) {                  remote.console.infoEL().append(html);                  remote.console.infoEL().get(0).lastChild.scrollIntoView();              }          },          // debug error          error: function (html) {              if (~remote.debug.indexOf("error")) {                  remote.console.errorEL().append(html);               }          },          // clear info/debug console          clear: function (s) {              if ("debug" == s) {                  remote.console.errorEL().html("");              } else {                  remote.console.infoEL().html("");              }          }      },            userAddress: function (user) {          if (user) {              if (!~user.indexOf("@")) {                  user += "@" + remote.jsjac.domain;// + "/" + remote.jsjac.resource;              } else if (~user.indexOf("/")) {                  user = user.substr(0, user.indexOf("/"));              }          }          return user;      },      jsjac: {          httpbase: window.contextPath + "/JHB/", //请求后台http-bind服务器url          domain: window["serverDomin"], //"192.168.5.231", // 192.168.5.231 当前有效域名          username: "",          pass: "",          timerval: 2000, // 设置请求超时          resource: "WebIM", // 链接资源标识          register: true // 是否注册      }  };  remote.jsjac.chat = {      writeReceiveMessage: function () {      },      setState: function () {          var onlineStatus = new Object();          onlineStatus["available"] = "在线";          onlineStatus["chat"] = "欢迎聊天";          onlineStatus["away"] = "离开";          onlineStatus["xa"] = "不可用";          onlineStatus["dnd"] = "请勿打扰";          onlineStatus["invisible"] = "隐身";          onlineStatus["unavailable"] = "离线";          remote.jsjac.chat.state = onlineStatus;          return onlineStatus;      },      state: null,      init: function () {          // Debugger plugin          if (typeof (Debugger) == "function") {              remote.dbger = new Debugger(2, remote.jsjac.resource);              remote.dbger.start();          } else {              // if you're using firebug or safari, use this for debugging              // oDbg = new JSJaCConsoleLogger(2);              // comment in above and remove comments below if you don't need debugging              remote.dbger = function () {              };              remote.dbger.log = function () {              };          }                    try {               // try to resume a session              if (JSJaCCookie.read("btype").getValue() == "binding") {                  remote.connection = new JSJaCHttpBindingConnection({ "oDbg": remote.dbger});                  rdbgerjac.chat.setupEvent(remote.connection);                  if (remote.connection.resume()) {                      remote.console.clear("debug");                  }              }           } catch (e) {              remote.console.errorEL().html(e.name + ":" + e.message);          } // reading cookie failed - never mind                    remote.jsjac.chat.setState();      },      login: function (loginForm) {          remote.console.clear("debug"); // reset          try {              // 链接参数              var connectionConfig = remote.jsjac;                            // Debugger console              if (typeof (oDbg) != "undefined") {                  connectionConfig.oDbg = oDbg;              }              var connection = new JSJaCHttpBindingConnection(connectionConfig);              remote.connection = connection;              // 安装(注册)Connection事件模型              remote.jsjac.chat.setupEvent(connection);                    // setup args for connect method              if (loginForm) {                  //connectionConfig = new Object();                  //connectionConfig.domain = loginForm.domain.value;                  connectionConfig.username = loginForm.userName.value;                  connectionConfig.pass = loginForm.password.value;                  connectionConfig.register = loginForm.register.checked;              }              // 连接服务器              connection.connect(connectionConfig);                            //remote.jsjac.chat.changeStatus("available", "online", 1, "chat");          } catch (e) {              remote.console.errorEL().html(e.toString());          } finally {              return false;          }      },      // 改变用户状态      changeStatus: function (type, status, priority, show) {          type = type || "unavailable";          status = status || "online";          priority = priority || "1";          show = show || "chat";          var presence = new JSJaCPresence();          presence.setType(type); // unavailable invisible          if (remote.connection) {              //remote.connection.send(presence);          }                    //presence = new JSJaCPresence();          presence.setStatus(status); // online          presence.setPriority(priority); // 1          presence.setShow(show); // chat          if (remote.connection) {              remote.connection.send(presence);          }      },            // 为Connection注册事件      setupEvent: function (con) {          var remoteChat = remote.jsjac.chat;          con.registerHandler('message', remoteChat.handleMessage);          con.registerHandler('presence', remoteChat.handlePresence);          con.registerHandler('iq', remoteChat.handleIQ);          con.registerHandler('onconnect', remoteChat.handleConnected);          con.registerHandler('onerror', remoteChat.handleError);          con.registerHandler('status_changed', remoteChat.handleStatusChanged);          con.registerHandler('ondisconnect', remoteChat.handleDisconnected);                con.registerIQGet('query', NS_VERSION, remoteChat.handleIqVersion);          con.registerIQGet('query', NS_TIME, remoteChat.handleIqTime);      },      // 发送远程消息      sendMessage: function (msg, to) {          try {              if (msg == "") {                  return false;              }              var user = "";              if (to) {                  if (!~to.indexOf("@")) {                      user += "@" + remote.jsjac.domain;                      to += "/" + remote.jsjac.resource;                  } else if (~to.indexOf("/")) {                      user = to.substr(0, to.indexOf("/"));                  }              } else {                  // 向chat接收信息区域写消息                  if (remote.jsjac.chat.writeReceiveMessage) {                      var html = "你没有指定发送者的名称";                      alert(html);                      //remote.jsjac.chat.writeReceiveMessage(receiverId, "server", html, false);                  }                  return false;              }              var userJID = "u" + hex_md5(user);              $("#" + userJID).find(remote.receiver).val(to);              // 构建jsjac的message对象              var message = new JSJaCMessage();              message.setTo(new JSJaCJID(to));              message.setType("chat"); // 单独聊天,默认为广播模式              message.setBody(msg);              // 发送消息              remote.connection.send(message);              return false;          } catch (e) {              var html = "
Error: " + e.message + "
"; remote.console.info(html); return false; } }, // 退出、断开链接 logout: function () { var presence = new JSJaCPresence(); presence.setType("unavailable"); if (remote.connection) { remote.connection.send(presence); remote.connection.disconnect(); } }, errorHandler: function (event) { var e = event || window.event; remote.console.errorEL().html(e); if (remote.connection && remote.connection.connected()) { remote.connection.disconnect(); } return false; }, unloadHandler: function () { var con = remote.connection; if (typeof con != "undefined" && con && con.connected()) { // save backend type if (con._hold) { // must be binding (new JSJaCCookie("btype", "binding")).write(); } if (con.suspend) { con.suspend(); } } }, writeMessage: function (userJID, userName, content) { // 向chat接收信息区域写消息 if (remote.jsjac.chat.writeReceiveMessage && !!content) { remote.jsjac.chat.writeReceiveMessage(userJID, userName, content, false); } }, // 重新连接服务器 reconnection: function () { remote.jsjac.register = false; if (remote.connection.connected()) { remote.connection.disconnect(); } remote.jsjac.chat.login(); }, /* ########################### Handler Event ############################# */ handleIQ: function (aIQ) { var html = "
IN (raw): " + aIQ.xml().htmlEnc() + "
"; remote.console.info(html); remote.connection.send(aIQ.errorReply(ERR_FEATURE_NOT_IMPLEMENTED)); }, handleMessage: function (aJSJaCPacket) { var user = aJSJaCPacket.getFromJID().toString(); //var userName = user.split("@")[0]; //var userJID = "u" + hex_md5(user); var content = aJSJaCPacket.getBody(); var html = ""; html += "
消息来自 " + user + ":
"; html += content.htmlEnc() + "
"; remote.console.info(html); $.WebIM.messageHandler(user, content); }, handlePresence: function (aJSJaCPacket) { var user = aJSJaCPacket.getFromJID(); var userName = user.toString().split("@")[0]; var html = "
"; if (!aJSJaCPacket.getType() && !aJSJaCPacket.getShow()) { html += "" + userName + " 上线了."; } else { html += "" + userName + " 设置 presence 为: "; if (aJSJaCPacket.getType()) { html += aJSJaCPacket.getType() + "."; } else { html += aJSJaCPacket.getShow() + "."; } if (aJSJaCPacket.getStatus()) { html += " (" + aJSJaCPacket.getStatus().htmlEnc() + ")"; } } html += "
"; remote.console.info(html); // 向chat接收信息区域写消息 remote.jsjac.chat.writeMessage("", userName, html); }, handleError: function (event) { var e = event || window.event; var html = "An error occured:
" + ("Code: " + e.getAttribute("code") + "\nType: " + e.getAttribute("type") + "\nCondition: " + e.firstChild.nodeName).htmlEnc(); remote.error(html); var content = ""; switch (e.getAttribute("code")) { case "401": content = "登陆验证失败!"; break; // 当注册发现重复,表明该用户已经注册,那么直接进行登陆操作 case "409": //content = "注册失败!\n\n请换一个用户名!"; remote.jsjac.chat.reconnection(); break; case "503": content = "无法连接到IM服务器,请检查相关配置!"; break; case "500": var contents = "服务器内部错误!\n\n连接断开!
重新连接"; remote.jsjac.chat.writeMessage("", "系统", contents); break; default: break; } if (content) { alert("WeIM: " + content); } if (remote.connection.connected()) { remote.connection.disconnect(); } }, // 状态变化触发事件 handleStatusChanged: function (status) { remote.console.info("
当前用户状态: " + status + "
"); remote.dbger.log("当前用户状态: " + status); if (status == "disconnecting") { var html = "你离线了!"; // 向chat接收信息区域写消息 remote.jsjac.chat.writeMessage("", "系统", html); } }, // 建立链接触发事件方法 handleConnected: function () { remote.console.clear("debug"); // reset remote.connection.send(new JSJaCPresence()); }, // 断开链接触发事件方法 handleDisconnected: function () { }, handleIqVersion: function (iq) { remote.connection.send(iq.reply([ iq.buildNode("name", remote.jsjac.resource), iq.buildNode("version", JSJaC.Version), iq.buildNode("os", navigator.userAgent) ])); return true; }, handleIqTime: function (iq) { var now = new Date(); remote.connection.send(iq.reply([ iq.buildNode("display", now.toLocaleString()), iq.buildNode("utc", now.jabberDate()), iq.buildNode("tz", now.toLocaleString().substring(now.toLocaleString().lastIndexOf(" ") + 1)) ])); return true; } };

个文件的代码就是用jsjac库和openfire建立通信的核心代码,代码中已经有注释,这里我就不再赘述。如果有什么不懂的可以给我留言。

4、消息区域、编辑器代码 send.message.editor-1.0.js

/**   * IM chat Send Message iframe editor   * @author: hoojo   * @email: hoojo_@126.com   * @blog: http://blog.csdn.net/IBM_hoojo    * @createDate: 2012-5-24   * @version 1.0   **/ var agent = window.navigator.userAgent.toLowerCase();  var sendMessageEditor = {          // 获取iframe的window对象      getWin: function () {          return /*!/firefox/.test(agent)*/false ? sendMessageEditor.iframe.contentWindow : window.frames[sendMessageEditor.iframe.name];      },         //获取iframe的document对象      getDoc: function () {          return !/firefox/.test(agent) ? sendMessageEditor.getWin().document : (sendMessageEditor.iframe.contentDocument || sendMessageEditor.getWin().document);      },         init: function (userJID) {          //打开document对象,向其写入初始化内容,以兼容FireFox          var doc = sendMessageEditor.getDoc();          doc.open();          var html = [              '',               '',              '',               ''].join("");          doc.write(html);          //打开document对象编辑模式          doc.designMode = "on";          doc.close();      },          getContent: function () {           var doc = sendMessageEditor.getDoc();           //获取编辑器的body对象          var body = doc.body || doc.documentElement;          //获取编辑器的内容          var content = body[xss_clean];          //对内容进行处理,例如替换其中的某些特殊字符等等          //Some code                    //返回内容          return content;       },               //统一的执行命令方法      execCmd: function (cmd, value, d){          var doc = d || sendMessageEditor.getDoc();          //doc对象的获取参照上面的代码          //调用execCommand方法执行命令          doc.execCommand(cmd, false, value === undefined ? null : value);      },            getStyleState: function (cmd) {          var doc = sendMessageEditor.getDoc();          //doc对象的获取参考上面的对面          //光标处是否是粗体          var state = doc.queryCommandState(cmd);          if(state){            //改变按钮的样式          }          return state;      },      insertAtCursor: function (text, d, w){          var doc = d || sendMessageEditor.getDoc();          var win = w || sendMessageEditor.getWin();          //win对象的获取参考上面的代码          if (/msie/.test(agent)) {              win.focus();              var r = doc.selection.createRange();              if (r) {                  r.collapse(true);                  r.pasteHTML(text);                    }          } else if (/gecko/.test(agent) || /opera/.test(agent)) {              win.focus();              sendMessageEditor.execCmd('InsertHTML', text, doc);          } else if (/safari/.test(agent)) {              sendMessageEditor.execCmd('InsertText', text, doc);          }      }  };

5、css样式 chat-2.0.css

/**   * function: im web chat css   * author: hoojo   * createDate: 2012-5-26 上午11:42:10   */ @CHARSET "UTF-8";     *, body {      font-family: Courier,serif,monospace;      font-size: 12px;      padding: 0;      margin: 0;      }     .chat-main {      position: absolute;      /*right: 80px;*/     left: 50px;      top: 20px;      z-index: 999;      display: none;  }     .chat-main .radius {      background-color: white;      border: 8px solid #94CADF;      border-radius: 1em;  }     #chat {      position: relative;      /*left: 150px;*/     padding: 0;      margin: 0;  }  #chat table {      border-collapse: collapse;      width: 435px;      *width: 460px;      /*width: 410px;*/     /*width: 320px;*/ }     #chat table .title {      font-weight: bold;      color: green;      padding: 3px;      background-color: #94CADF;  }     /* 收缩条 */ #chat table .split {      background-color: #94CADF;      cursor: pointer;  }     /* ################## product info #################### */ #chat table .product-info {      width: 30%;      /*display: none;*/     padding: 0;      margin: 0;      vertical-align: top;  }     #chat table .product-info ul {      margin: 0;      padding: 0;  }     #chat table .product-info ul div.header {      background-color: #EBEFFE;      line-height: 22px;      font-size: 12px;      color: black;  }     #chat table .product-info ul li {      list-style: none outside none;      background-color: white;      text-overflow: ellipsis;      white-space: nowrap;      overflow: hidden;      padding-left: 5px;      line-height: 22px;      font-size: 11px;      color: #6F6F6F;      width: 140px;  }     #chat table .product-info ul li.pic {      height: 200px;      padding: 0 5px 0 5px;      border: 1px dashed #ccc;      text-align: center;  }     #chat table .product-info ul li.pic img {  }     #chat table .product-info ul li.product-name {      font-weight: bold;      color: black;  }     #chat table .product-info ul li.price span {      font-family: Courier;      font-size: 16px;      font-weight: bold;      color: #ED4E08;  }     #chat table .product-info ul li.market-price s {      color: black;  }     #chat table .product-info ul li a {      float: right;  }     #chat table .product-info ul li.info {      display: none;  }     /*########### 接收消息区域 ############ */ #chat table .receive-message {      height: 250px;  }     #chat table .send-message {      width: 100%;      /*height: auto;*/ }     #chat table td {      /*border: 1px solid white;*/ }     #chat table .bottom-bar {      background-color: #94CADF;      text-align: right;  }     /* ############## 工具条 ################# start */ #chat table .tool-bar {      height: 25px;      background-color: #94CADF;  }     #chat table .tool-bar select {      float: left;  }     #chat table .tool-bar select.family {      width: 45px;      *width: 55px;  }     #chat table .tool-bar div {      width: 17px;      height: 16px;      float: left;      cursor: pointer;      margin-right: 2px;      margin-top: 1px;      *margin-top: 2px;      background: transparent url("../images/tb-sprite.gif") no-repeat scroll 0 0;  }     #chat table .tool-bar .color {      margin-left: 2px;      background-position: -159px 0;  }  #chat table .tool-bar .bold {      /*background-position: 0 0;*/ }  #chat table .tool-bar .italic {      background-position: -18px 0;  }  #chat table .tool-bar .underline {      background-position: -32px 0;  }  #chat table .tool-bar .face {      margin: 2px 0 0 3px;      background-image: url("../images/facehappy.gif");  }  #chat table .tool-bar .history {      background-image: none;      width: 60px;      float: right;      margin-top: 3px;      font-size: 12px;      display: none;  }  /* ###### 表情 ###### */ #chat #face {      border: 1px solid black;      width: 275px;      *width: 277px;      position: relative;      left: 8px;      top: -370px;      _top: -359px;      z-index: 3;      display: none;  }     #chat #face img {      border: 1px solid #ccc;      border-right: none;      border-bottom: none;       cursor: pointer;  }     #send {      width: 90px;      height: 25px;  }  #close {      width: 40px;      height: 25px;  }     .chat-message {      position: absolute;       bottom: 0;       left: 0;       width: 100%;       height: 25px;       background-color: #fcfcfc;  }     .no-msg, .have-msg {      cursor: pointer;       float: right;       margin: 5px 5px 0 0;  }

6、web.xml配置

  感谢各位的阅读,以上就是"怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序"的内容了,经过本文的学习后,相信大家对怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0