281 lines
6.5 KiB
JavaScript
281 lines
6.5 KiB
JavaScript
/*!
|
||
* jQuery Sina Emotion v2.1.0
|
||
* http://www.clanfei.com/
|
||
*
|
||
* Copyright 2012-2014 Lanfei
|
||
* Released under the MIT license
|
||
*
|
||
* Date: 2014-05-19T20:10:23+0800
|
||
*/
|
||
(function($) {
|
||
|
||
var $target;
|
||
|
||
var options;
|
||
|
||
var emotions;
|
||
|
||
var categories;
|
||
|
||
var emotionsMap;
|
||
|
||
var parsingArray = [];
|
||
|
||
var defCategory = '默认';
|
||
|
||
var initEvents = function() {
|
||
$('body').bind({
|
||
click: function() {
|
||
$('#sinaEmotion').hide();
|
||
}
|
||
});
|
||
|
||
$('#sinaEmotion').bind({
|
||
click: function(event) {
|
||
event.stopPropagation();
|
||
}
|
||
}).delegate('.prev', {
|
||
click: function(event) {
|
||
var page = $('#sinaEmotion .categories').data('page');
|
||
showCatPage(page - 1);
|
||
event.preventDefault();
|
||
}
|
||
}).delegate('.next', {
|
||
click: function(event) {
|
||
var page = $('#sinaEmotion .categories').data('page');
|
||
showCatPage(page + 1);
|
||
event.preventDefault();
|
||
}
|
||
}).delegate('.category', {
|
||
click: function(event) {
|
||
$('#sinaEmotion .categories .current').removeClass('current');
|
||
showCategory($.trim($(this).addClass('current').text()));
|
||
event.preventDefault();
|
||
}
|
||
}).delegate('.page', {
|
||
click: function(event) {
|
||
$('#sinaEmotion .pages .current').removeClass('current');
|
||
var page = parseInt($(this).addClass('current').text() - 1);
|
||
showFacePage(page);
|
||
event.preventDefault();
|
||
}
|
||
}).delegate('.face', {
|
||
click: function(event) {
|
||
$('#sinaEmotion').hide();
|
||
$target.insertText($(this).children('img').prop('alt'));
|
||
event.preventDefault();
|
||
}
|
||
});
|
||
};
|
||
|
||
var loadEmotions = function(callback) {
|
||
|
||
if(emotions){
|
||
callback && callback();
|
||
return;
|
||
}
|
||
|
||
if (!options) {
|
||
options = $.fn.sinaEmotion.options;
|
||
}
|
||
|
||
emotions = {};
|
||
categories = [];
|
||
emotionsMap = {};
|
||
|
||
$('body').append('<div id="sinaEmotion">正在加载,请稍后...</div>');
|
||
|
||
initEvents();
|
||
|
||
$.getJSON('https://api.weibo.com/2/emotions.json?callback=?', {
|
||
source: options.appKey,
|
||
language: options.language
|
||
}, function(json) {
|
||
|
||
var item, category;
|
||
var data = json.data;
|
||
|
||
$('#sinaEmotion').html('<div class="right"><a href="#" class="prev">«</a><a href="#" class="next">»</a></div><ul class="categories"></ul><ul class="faces"></ul><ul class="pages"></ul>');
|
||
|
||
for (var i = 0, l = data.length; i < l; ++i) {
|
||
item = data[i];
|
||
category = item.category || defCategory;
|
||
|
||
if (!emotions[category]) {
|
||
emotions[category] = [];
|
||
categories.push(category);
|
||
}
|
||
|
||
emotions[category].push({
|
||
icon: item.icon,
|
||
phrase: item.phrase
|
||
});
|
||
|
||
emotionsMap[item.phrase] = item.icon;
|
||
}
|
||
|
||
$(parsingArray).parseEmotion();
|
||
parsingArray = null;
|
||
|
||
callback && callback();
|
||
});
|
||
};
|
||
|
||
var showCatPage = function(page) {
|
||
|
||
var html = '';
|
||
var length = categories.length;
|
||
var maxPage = Math.ceil(length / 5);
|
||
var $categories = $('#sinaEmotion .categories');
|
||
var category = $categories.data('category') || defCategory;
|
||
|
||
page = (page + maxPage) % maxPage;
|
||
|
||
for (var i = page * 5; i < length && i < (page + 1) * 5; ++i) {
|
||
html += '<li class="item"><a href="#" class="category' + (category == categories[i] ? ' current' : '') + '">' + categories[i] + '</a></li>';
|
||
}
|
||
|
||
$categories.data('page', page).html(html);
|
||
};
|
||
|
||
var showCategory = function(category) {
|
||
$('#sinaEmotion .categories').data('category', category);
|
||
showFacePage(0);
|
||
showPages();
|
||
};
|
||
|
||
var showFacePage = function(page) {
|
||
|
||
var face;
|
||
var html = '';
|
||
var pageHtml = '';
|
||
var rows = options.rows;
|
||
var category = $('#sinaEmotion .categories').data('category');
|
||
var faces = emotions[category];
|
||
page = page || 0;
|
||
|
||
for (var i = page * rows, l = faces.length; i < l && i < (page + 1) * rows; ++i) {
|
||
face = faces[i];
|
||
html += '<li class="item"><a href="#" class="face"><img class="sina-emotion" src="' + face.icon + '" alt="' + face.phrase + '" /></a></li>';
|
||
}
|
||
|
||
$('#sinaEmotion .faces').html(html);
|
||
};
|
||
|
||
var showPages = function() {
|
||
|
||
var html = '';
|
||
var rows = options.rows;
|
||
var category = $('#sinaEmotion .categories').data('category');
|
||
var faces = emotions[category];
|
||
var length = faces.length;
|
||
|
||
if (length > rows) {
|
||
for (var i = 0, l = Math.ceil(length / rows); i < l; ++i) {
|
||
html += '<li class="item"><a href="#" class="page' + (i == 0 ? ' current' : '') + '">' + (i + 1) + '</a></li>';
|
||
}
|
||
$('#sinaEmotion .pages').html(html).show();
|
||
} else {
|
||
$('#sinaEmotion .pages').hide();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 为某个元素设置点击事件,点击弹出表情选择窗口
|
||
* @param {[type]} target [description]
|
||
* @return {[type]} [description]
|
||
*/
|
||
$.fn.sinaEmotion = function(target) {
|
||
|
||
target = target || function(){
|
||
return $(this).parents('form').find('textarea,input[type=text]').eq(0);
|
||
};
|
||
|
||
var $that = $(this).last();
|
||
var offset = $that.offset();
|
||
|
||
if($that.is(':visible')){
|
||
if(typeof target == 'function'){
|
||
$target = target.call($that);
|
||
}else{
|
||
$target = $(target);
|
||
}
|
||
|
||
loadEmotions(function(){
|
||
showCategory(defCategory);
|
||
showCatPage(0);
|
||
});
|
||
$('#sinaEmotion').css({
|
||
top: offset.top + $that.outerHeight() + 5,
|
||
left: offset.left
|
||
}).show();
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
$.fn.parseEmotion = function() {
|
||
|
||
if(! categories){
|
||
parsingArray = $(this);
|
||
loadEmotions();
|
||
}else if(categories.length == 0){
|
||
parsingArray = parsingArray.add($(this));
|
||
}else{
|
||
$(this).each(function() {
|
||
|
||
var $this = $(this);
|
||
var html = $this.html();
|
||
|
||
html = html.replace(/<.*?>/g, function($1) {
|
||
$1 = $1.replace('[', '[');
|
||
$1 = $1.replace(']', ']');
|
||
return $1;
|
||
}).replace(/\[[^\[\]]*?\]/g, function($1) {
|
||
var url = emotionsMap[$1];
|
||
if (url) {
|
||
return '<img class="sina-emotion" src="' + url + '" alt="' + $1 + '" />';
|
||
}
|
||
return $1;
|
||
});
|
||
|
||
$this.html(html);
|
||
});
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
$.fn.insertText = function(text) {
|
||
|
||
this.each(function() {
|
||
|
||
if (this.tagName !== 'INPUT' && this.tagName !== 'TEXTAREA') {
|
||
return;
|
||
}
|
||
if (document.selection) {
|
||
this.focus();
|
||
var cr = document.selection.createRange();
|
||
cr.text = text;
|
||
cr.collapse();
|
||
cr.select();
|
||
} else if (this.selectionStart !== undefined) {
|
||
var start = this.selectionStart;
|
||
var end = this.selectionEnd;
|
||
this.value = this.value.substring(0, start) + text + this.value.substring(end, this.value.length);
|
||
this.selectionStart = this.selectionEnd = start + text.length;
|
||
} else {
|
||
this.value += text;
|
||
}
|
||
});
|
||
|
||
return this;
|
||
}
|
||
|
||
$.fn.sinaEmotion.options = {
|
||
rows: 72, // 每页显示的表情数
|
||
language: 'cnname', // 简体(cnname)、繁体(twname)
|
||
appKey: '1362404091' // 新浪微博开放平台的应用ID
|
||
};
|
||
})(jQuery);
|