中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

發布時間:2021-11-18 11:27:22 來源:億速云 閱讀:110 作者:iii 欄目:web開發

這篇文章主要講解了“怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序”吧!

此程序可以和所有連接到Openfire服務器的應用進行通信、發送消息。如果要運行本程序還需要一個聊天服務器Openfire,

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

JabberHTTPBind是jabber提供的XMPP協議通信的Http bind發送的形式,它可以完成WebBrowser和Openfire建立長連接通信。

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

可以發送表情、改變字體樣式(對方界面也可以看到你的字體樣式),同時右側是顯示/收縮詳情的信息

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

收縮詳情

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

聊天界面部分截圖

用戶登錄、注冊,sendTo表示你登錄后向誰發送聊天消息、并且建立一個聊天窗口

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

登錄成功后,你可以在日志控制臺看到你的登陸狀態、或是在firebug控制臺中看到你的連接請求狀態

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

登陸失敗

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

只有connecting,就沒有下文了

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

登陸成功后,你就可以給指定用戶發送消息,且設置你想發送消息的新用戶點擊new Chat按鈕創建新會話

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

如果你來了新消息,在瀏覽器的標題欄會有新消息提示

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

如果你當前聊天界面的窗口都是關閉狀態,那么在右下角會有消息提示的閃動圖標

開發環境

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

開發依賴庫

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

jdk1.4+

serializer.jar

xalan.jar

jhb-1.0.jar

log4j-1.2.16.jar

jhb-1.0.jar 這個就是JabberHTTPBind,我把編譯的class打成jar包了

JavaScript lib

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

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

工程目錄結構

怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序

二、核心代碼演示

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

<%@ page language="java" pageEncoding="UTF-8" %> <%  String path = request.getContextPath();  String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  %>    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>   <head>     <base href="<%=basePath%>">           <title>WebIM Chat</title>     <meta http-equiv="pragma" content="no-cache">     <meta http-equiv="cache-control" content="no-cache">     <meta http-equiv="expires" content="0">          <meta http-equiv="author" content="hoojo">     <meta http-equiv="email" content="hoojo_@126.com">     <meta http-equiv="blog" content="http://blog.csdn.net/IBM_hoojo">     <meta http-equiv="blog" content="http://hoojo.cnblogs.com">     <link rel="stylesheet" type="text/css" href="css/chat-2.0.css" />     <script type="text/javascript">         window.contextPath = "<%=path%>";          window["serverDomin"] = "192.168.8.22";      </script>     <script type="text/javascript" src="jslib/jquery-1.7.1.min.js"></script>     <script type="text/javascript" src="jslib/jsjac.js"></script>     <!-- script type="text/javascript" src="debugger/Debugger.js"></script-->     <script type="text/javascript" src="jslib/send.message.editor-1.0.js"></script>     <script type="text/javascript" src="jslib/jquery.easydrag.js"></script>     <script type="text/javascript" src="jslib/remote.jsjac.chat-2.0.js"></script>     <script type="text/javascript" src="jslib/local.chat-2.0.js"></script>     <script type="text/javascript">         $(function () {                            $("#login").click(function () {                  var userName = $(":text[name='userName']").val();                  var receiver = $("*[name='to']").val();                  // 建立一個聊天窗口應用,并設置發送者和消息接收者                  $.WebIM({                      sender: userName,                      receiver: receiver                  });                  // 登陸到openfire服務器                   remote.jsjac.chat.login(document.userForm);                   $("label").text(userName);                   $("form").hide();                   $("#newConn").show();              });                            $("#logout").click(function () {                   // 退出openfire登陸,斷開鏈接                   remote.jsjac.chat.logout();                   $("form").show();                   $("#newConn").hide();                   $("#chat").hide(800);              });                            $("#newSession").click(function () {                  var receiver = $("#sendTo").val();                  // 建立一個新聊天窗口,并設置消息接收者(發送給誰?)                  $.WebIM.newWebIM({                      receiver: receiver                  });              });          });      </script>   </head>       <body>     <!-- 登陸表單 -->     <form name="userForm" style="background-color: #fcfcfc; width: 100%;">         userName:<input type="text" name="userName" value="boy"/>         password:<input type="password" name="password" value="boy"/>                   register: <input type="checkbox" name="register"/>         sendTo: <input type="text" id="to" name="to" value="hoojo" width="10"/>         <input type="button" value="Login" id="login"/>       </form>     <!-- 新窗口聊天 -->     <div id="newConn" style="display: none; background-color: #fcfcfc; width: 100%;">            User:<label></label>            sendTo: <input type="text" id="sendTo" value="hoojo" width="10"/>            <input type="button" value="new Chat" id="newSession"/>              <input type="button" value="Logout" id="logout"/>     </div>     <!-- 日志信息 -->     <div id="error" style="display: ; background-color: red;"></div>     <div id="info" style="display: ; background-color: #999999;"></div>     <!-- 聊天來消息提示 -->     <div class="chat-message">         <img src="images/write_icon.png" class="no-msg"/>         <img src="images/write_icon.gif" class="have-msg" style="display: none;"/>     </div>   </body> </html>

下面這段代碼尤為重要,它是設置你鏈接openfire的地址。這個地址一段錯誤你將無法進行通信!

<script type="text/javascript">      window.contextPath = "<%=path%>";      window["serverDomin"] = "192.168.8.22";  </script>

$.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: [              '<html>',                  '<head><style type="text/css">',                  'body{border:0;margin:0;padding:3px;height:98%;cursor:text;background-color:white;font-size:12px;font-family:Courier,serif,monospace;}',                  '.msg{margin-left: 1em;}p{margin:0;padding:0;}.me{color: blue;}.you{color:green;}',                  '</style></head>',                  '<body></body>',              '</html>'         ].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 = [ "<span style='", styleTpl, "'>", content, "</span>" ].join("");              }              return [                  '<p class="', userCls, '">', _opts.getDatetime(), '  ', userName, ':</p>',                  '<p class="msg">', content, '</p>'             ].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.innerHTML;              content = $.trim(content);              content = content.replace(new RegExp("<br>", "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 = [ "<span style='", styleTpl, "'>", content, "</span>" ].join("");                      remote.jsjac.chat.sendMessage(content, receiver);                  }                                    // 清空發送區域                  $(doc).find("body").html("");              }          },                     faceImagePath: "images/emotions/",          faceElTpl: function (i) {              return [                  "<img src='",                  this.faceImagePath,                  (i - 1),                  "fixed.bmp' gif='",                  this.faceImagePath,                  (i - 1),                  ".gif'/>"             ].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("<br/>");                   }               }              $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 = "<img src='" + $(this).attr("gif") + "'/>";                   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 = ['<style type="text/css">body{', styleTpl,'}</style>'].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 [              '<div class="chat-main" id="', userJID,                  '" sender="', sender, '" receiver="', receiver, '">',                                        '<div id="chat"><div class="radius">',                      '<table>',                          '<tr>',                              '<td colspan="3" class="title"></td>',                          '</tr>',                          '<tr>',                              '<td class="receive-message">',                                  '<iframe name="receiveMessage', userJID,'" frameborder="0" width="100%" height="100%"></iframe>',                              '</td>',                              '<td rowspan="4" class="split" ', display, '></td>',                              '<td rowspan="4" class="product-info" ', display, '>',                                  '<ul>',                                      '<div class="header">商品詳情</div>',                                      '<li class="pic">',                                      '<img src="', product.pic, '"/></li>',                                      '<li class="product-name">', product.name, '</li>',                                      '<li class="price">團購價:<span>', product.price, '</span>元</li>',                                      '<li class="market-price">市場價:<s><i>', product.marketPrice, '</i></s>元</li>',                                      '<li>快遞公司:', product.deliverOrgs, '</li>',                                      '<li>倉庫:', product.wareHouses, '</li>',                                      product.skuAttrs,                                  '</ul>',                              '</td>',                          '</tr>',                          '<tr class="tool-bar">',                              '<td>',                                  '<select name="font-family" class="family">',                                      '<option>宋體</option>',                                      '<option>黑體</option>',                                      '<option>幼圓</option>',                                      '<option>華文行楷</option>',                                      '<option>華文楷體</option>',                                      '<option>華文楷體</option>',                                      '<option>華文彩云</option>',                                      '<option>華文隸書</option>',                                      '<option>微軟雅黑</option>',                                      '<option>Fixedsys</option>',                                  '</select>',                                                                    '<select name="font-size">',                                      '<option value="12px">大小</option>',                                      '<option value="10px">10</option>',                                      '<option value="12px">12</option>',                                      '<option value="14px">14</option>',                                      '<option value="16px">16</option>',                                      '<option value="18px">18</option>',                                      '<option value="20px">20</option>',                                      '<option value="24px">24</option>',                                      '<option value="28px">28</option>',                                      '<option value="36px">36</option>',                                      '<option value="42px">42</option>',                                      '<option value="52px">52</option>',                                  '</select>',                                  '<select name="color">',                                      '<option value="" selected="selected">顏色</option>',                                      '<option value="#000000" style="background-color:#000000"></option>',                                      '<option value="#FFFFFF" style="background-color:#FFFFFF"></option>',                                      '<option value="#008000" style="background-color:#008000"></option>',                                      '<option value="#800000" style="background-color:#800000"></option>',                                      '<option value="#808000" style="background-color:#808000"></option>',                                      '<option value="#000080" style="background-color:#000080"></option>',                                      '<option value="#800080" style="background-color:#800080"></option>',                                      '<option value="#808080" style="background-color:#808080"></option>',                                      '<option value="#FFFF00" style="background-color:#FFFF00"></option>',                                      '<option value="#00FF00" style="background-color:#00FF00"></option>',                                      '<option value="#00FFFF" style="background-color:#00FFFF"></option>',                                      '<option value="#FF00FF" style="background-color:#FF00FF"></option>',                                      '<option value="#FF0000" style="background-color:#FF0000"></option>',                                      '<option value="#0000FF" style="background-color:#0000FF"></option>',                                      '<option value="#008080" style="background-color:#008080"></option>',                                  '</select>',                                  '<div class="bold"></div>',                                  '<div class="underline"></div>',                                  '<div class="italic"></div>',                                  '<div class="face"></div>',                                  '<div class="history">消息記錄</div>',                              '</td>',                          '</tr>',                          '<tr class="send-message">',                              '<td>',                                  '<iframe name="sendMessage', userJID,'" width="100%" height="80px" frameborder="0"></iframe>',                              '</td>',                          '</tr>',                          '<tr class="bottom-bar">',                              '<td><input type="text" id="to" name="to" value="hoojo" style="width: 100px; display: none;"/><input type="button" value="關閉" id="close"/>',                              '<input type="button" value="發送(Enter)" id="send"/> </td>',                          '</tr>',                      '</table></div>',                      '<div id="face"></div>',                  '</div>',              '</div>'             ].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 = "<div class='msg error''>Error: " + e.message + "</div>";              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 = "<div class='msg'>IN (raw): " + aIQ.xml().htmlEnc() + "</div>";          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 += "<div class=\"msg\"><b>消息來自 " + user + ":</b><br/>";          html += content.htmlEnc() + "</div>";          remote.console.info(html);                    $.WebIM.messageHandler(user, content);      },      handlePresence: function (aJSJaCPacket) {          var user = aJSJaCPacket.getFromJID();          var userName = user.toString().split("@")[0];          var html = "<div class=\"msg\">";          if (!aJSJaCPacket.getType() && !aJSJaCPacket.getShow()) {              html += "<b>" + userName + " 上線了.</b>";          } else {              html += "<b>" + userName + " 設置 presence 為: ";              if (aJSJaCPacket.getType()) {                  html += aJSJaCPacket.getType() + ".</b>";              } else {                  html += aJSJaCPacket.getShow() + ".</b>";              }              if (aJSJaCPacket.getStatus()) {                  html += " (" + aJSJaCPacket.getStatus().htmlEnc() + ")";              }          }          html += "</div>";          remote.console.info(html);                    // 向chat接收信息區域寫消息          remote.jsjac.chat.writeMessage("", userName, html);      },      handleError: function (event) {          var e = event || window.event;          var html = "An error occured:<br />"               + ("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連接斷開!<br/><a href='javascript: self.parent.remote.jsjac.chat.reconnection();'>重新連接</a>";                  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("<div>當前用戶狀態: " + status + "</div>");          remote.dbger.log("當前用戶狀態: " + status);          if (status == "disconnecting") {              var html = "<b style='color:red;'>你離線了!</b>";              // 向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 = [              '<html>',               '<head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;background-color:white;font-size:12px;font-family:Courier,serif,monospace;}</style></head>',              '<body jid="', userJID, '"></body>',               '</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.innerHTML;          //對內容進行處理,例如替換其中的某些特殊字符等等          //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配置

<?xml version="1.0" encoding="UTF-8"?>  <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   >      <servlet>          <servlet-name>Jabber HTTP Binding Servlet</servlet-name>          <servlet-class>org.jabber.JabberHTTPBind.JHBServlet</servlet-class>          <!--           <init-param>              <param-name>debug</param-name>              <param-value>1</param-value>          </init-param>           -->      </servlet>         <servlet-mapping>          <servlet-name>Jabber HTTP Binding Servlet</servlet-name>          <url-pattern>/JHB/</url-pattern>      </servlet-mapping>         <welcome-file-list>          <welcome-file>index.jsp</welcome-file>      </welcome-file-list>  </web-app>

感謝各位的閱讀,以上就是“怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序”的內容了,經過本文的學習后,相信大家對怎么用JavaScript和jQuery構建一個BS Web的聊天應用程序這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永昌县| 房产| 察雅县| 浑源县| 顺平县| 托里县| 临泽县| 林口县| 咸阳市| 呼伦贝尔市| 孟连| 韶山市| 乌兰察布市| 万山特区| 吕梁市| 揭西县| 富源县| 会宁县| 二连浩特市| 宁都县| 鹤山市| 通城县| 衡南县| 麻栗坡县| 宜兰市| 泽州县| 嘉峪关市| 丰宁| 江口县| 宜阳县| 赞皇县| 玉屏| 田东县| 赣榆县| 南宫市| 芦山县| 江西省| 晋江市| 岑巩县| 卢龙县| 淳安县|