千家信息网

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

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要讲解了"怎么用JavaScript和jQuery构建一个BS Web的聊天应用程序",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用Ja
千家信息网最后更新 2025年11月07日怎么用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的聊天应用程序这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

消息 代码 方法 事件 区域 用户 服务器 服务 通信 信息 对象 链接 程序 应用 登陆 内容 状态 样式 核心 表情 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 面向对象软件开发英文文献 湖北智能养老软件开发公司 象山敏捷软件开发服务 苹果登陆qq邮箱服务器没响应 一种基于图数据库的商品推荐算法 湖南服务器虚拟化优势 360卫士服务器防护 网络安全审核员 服务器输入输出处理部件 深圳物联网软件开发机构 软件开发项目补充费用文档 近几年网络安全原理论文 梦幻西游山东百花园服务器怎么进 怀旧服魔兽服务器人数查询 浏览器与服务器断开连接怎么处理 网络安全管理讲座 全球攻势手游先行服怎么进服务器 网络安全法可断网 数据库更换字段名 崇义网络安全宣传周 数据库password算法 荣耀10怎么重启数据库 360卫士服务器防护 科密A1出现数据库连接失败 黑龙江省游戏软件开发 高校加强网络安全防护 中兴云服务器和浪潮云服务器 全球攻势手游先行服怎么进服务器 怎么查服务器真实ip 湖北智能软件开发
0