jquery-sinaEmotion-2.1.0.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*!
  2. * jQuery Sina Emotion v2.1.0
  3. * http://www.clanfei.com/
  4. *
  5. * Copyright 2012-2014 Lanfei
  6. * Released under the MIT license
  7. *
  8. * Date: 2014-05-19T20:10:23+0800
  9. */
  10. (function($) {
  11. var $target;
  12. var options;
  13. var emotions;
  14. var categories;
  15. var emotionsMap;
  16. var parsingArray = [];
  17. var defCategory = '默认';
  18. var initEvents = function() {
  19. $('body').bind({
  20. click: function() {
  21. $('#sinaEmotion').hide();
  22. }
  23. });
  24. $('#sinaEmotion').bind({
  25. click: function(event) {
  26. event.stopPropagation();
  27. }
  28. }).delegate('.prev', {
  29. click: function(event) {
  30. var page = $('#sinaEmotion .categories').data('page');
  31. showCatPage(page - 1);
  32. event.preventDefault();
  33. }
  34. }).delegate('.next', {
  35. click: function(event) {
  36. var page = $('#sinaEmotion .categories').data('page');
  37. showCatPage(page + 1);
  38. event.preventDefault();
  39. }
  40. }).delegate('.category', {
  41. click: function(event) {
  42. $('#sinaEmotion .categories .current').removeClass('current');
  43. showCategory($.trim($(this).addClass('current').text()));
  44. event.preventDefault();
  45. }
  46. }).delegate('.page', {
  47. click: function(event) {
  48. $('#sinaEmotion .pages .current').removeClass('current');
  49. var page = parseInt($(this).addClass('current').text() - 1);
  50. showFacePage(page);
  51. event.preventDefault();
  52. }
  53. }).delegate('.face', {
  54. click: function(event) {
  55. $('#sinaEmotion').hide();
  56. $target.insertText($(this).children('img').prop('alt'));
  57. event.preventDefault();
  58. }
  59. });
  60. };
  61. var loadEmotions = function(callback) {
  62. if(emotions){
  63. callback && callback();
  64. return;
  65. }
  66. if (!options) {
  67. options = $.fn.sinaEmotion.options;
  68. }
  69. emotions = {};
  70. categories = [];
  71. emotionsMap = {};
  72. $('body').append('<div id="sinaEmotion">正在加载,请稍后...</div>');
  73. initEvents();
  74. $.getJSON('https://api.weibo.com/2/emotions.json?callback=?', {
  75. source: options.appKey,
  76. language: options.language
  77. }, function(json) {
  78. var item, category;
  79. var data = json.data;
  80. $('#sinaEmotion').html('<div class="right"><a href="#" class="prev">&laquo;</a><a href="#" class="next">&raquo;</a></div><ul class="categories"></ul><ul class="faces"></ul><ul class="pages"></ul>');
  81. for (var i = 0, l = data.length; i < l; ++i) {
  82. item = data[i];
  83. category = item.category || defCategory;
  84. if (!emotions[category]) {
  85. emotions[category] = [];
  86. categories.push(category);
  87. }
  88. emotions[category].push({
  89. icon: item.icon,
  90. phrase: item.phrase
  91. });
  92. emotionsMap[item.phrase] = item.icon;
  93. }
  94. $(parsingArray).parseEmotion();
  95. parsingArray = null;
  96. callback && callback();
  97. });
  98. };
  99. var showCatPage = function(page) {
  100. var html = '';
  101. var length = categories.length;
  102. var maxPage = Math.ceil(length / 5);
  103. var $categories = $('#sinaEmotion .categories');
  104. var category = $categories.data('category') || defCategory;
  105. page = (page + maxPage) % maxPage;
  106. for (var i = page * 5; i < length && i < (page + 1) * 5; ++i) {
  107. html += '<li class="item"><a href="#" class="category' + (category == categories[i] ? ' current' : '') + '">' + categories[i] + '</a></li>';
  108. }
  109. $categories.data('page', page).html(html);
  110. };
  111. var showCategory = function(category) {
  112. $('#sinaEmotion .categories').data('category', category);
  113. showFacePage(0);
  114. showPages();
  115. };
  116. var showFacePage = function(page) {
  117. var face;
  118. var html = '';
  119. var pageHtml = '';
  120. var rows = options.rows;
  121. var category = $('#sinaEmotion .categories').data('category');
  122. var faces = emotions[category];
  123. page = page || 0;
  124. for (var i = page * rows, l = faces.length; i < l && i < (page + 1) * rows; ++i) {
  125. face = faces[i];
  126. html += '<li class="item"><a href="#" class="face"><img class="sina-emotion" src="' + face.icon + '" alt="' + face.phrase + '" /></a></li>';
  127. }
  128. $('#sinaEmotion .faces').html(html);
  129. };
  130. var showPages = function() {
  131. var html = '';
  132. var rows = options.rows;
  133. var category = $('#sinaEmotion .categories').data('category');
  134. var faces = emotions[category];
  135. var length = faces.length;
  136. if (length > rows) {
  137. for (var i = 0, l = Math.ceil(length / rows); i < l; ++i) {
  138. html += '<li class="item"><a href="#" class="page' + (i == 0 ? ' current' : '') + '">' + (i + 1) + '</a></li>';
  139. }
  140. $('#sinaEmotion .pages').html(html).show();
  141. } else {
  142. $('#sinaEmotion .pages').hide();
  143. }
  144. };
  145. /**
  146. * 为某个元素设置点击事件,点击弹出表情选择窗口
  147. * @param {[type]} target [description]
  148. * @return {[type]} [description]
  149. */
  150. $.fn.sinaEmotion = function(target) {
  151. target = target || function(){
  152. return $(this).parents('form').find('textarea,input[type=text]').eq(0);
  153. };
  154. var $that = $(this).last();
  155. var offset = $that.offset();
  156. if($that.is(':visible')){
  157. if(typeof target == 'function'){
  158. $target = target.call($that);
  159. }else{
  160. $target = $(target);
  161. }
  162. loadEmotions(function(){
  163. showCategory(defCategory);
  164. showCatPage(0);
  165. });
  166. $('#sinaEmotion').css({
  167. top: offset.top + $that.outerHeight() + 5,
  168. left: offset.left
  169. }).show();
  170. }
  171. return this;
  172. };
  173. $.fn.parseEmotion = function() {
  174. if(! categories){
  175. parsingArray = $(this);
  176. loadEmotions();
  177. }else if(categories.length == 0){
  178. parsingArray = parsingArray.add($(this));
  179. }else{
  180. $(this).each(function() {
  181. var $this = $(this);
  182. var html = $this.html();
  183. html = html.replace(/<.*?>/g, function($1) {
  184. $1 = $1.replace('[', '&#91;');
  185. $1 = $1.replace(']', '&#93;');
  186. return $1;
  187. }).replace(/\[[^\[\]]*?\]/g, function($1) {
  188. var url = emotionsMap[$1];
  189. if (url) {
  190. return '<img class="sina-emotion" src="' + url + '" alt="' + $1 + '" />';
  191. }
  192. return $1;
  193. });
  194. $this.html(html);
  195. });
  196. }
  197. return this;
  198. };
  199. $.fn.insertText = function(text) {
  200. this.each(function() {
  201. if (this.tagName !== 'INPUT' && this.tagName !== 'TEXTAREA') {
  202. return;
  203. }
  204. if (document.selection) {
  205. this.focus();
  206. var cr = document.selection.createRange();
  207. cr.text = text;
  208. cr.collapse();
  209. cr.select();
  210. } else if (this.selectionStart !== undefined) {
  211. var start = this.selectionStart;
  212. var end = this.selectionEnd;
  213. this.value = this.value.substring(0, start) + text + this.value.substring(end, this.value.length);
  214. this.selectionStart = this.selectionEnd = start + text.length;
  215. } else {
  216. this.value += text;
  217. }
  218. });
  219. return this;
  220. }
  221. $.fn.sinaEmotion.options = {
  222. rows: 72, // 每页显示的表情数
  223. language: 'cnname', // 简体(cnname)、繁体(twname)
  224. appKey: '1362404091' // 新浪微博开放平台的应用ID
  225. };
  226. })(jQuery);