一个非常好用的emoji插件
如何利用该插件迅速搭建搭建emoji界面?
在主布局文件下写下如下代码
<script>
var $wysiwyg = $('.emojis-wysiwyg').emojiarea({wysiwyg: true,button: '.showemoji'});
//button: '.showemoji' 则是用于自定义打开emoji选择界面的按钮的样式
//emojis-wysiwyg则是textarea对应的class,该操作用于创建一个div与我们的textarea绑定
</script>
分析源码
jquery-emojiarea.js
数据存储与emojiarea构造方法
//$.fx是类级别的插件开发,即给jQuery添加新的全局函数
$.emojiarea = {
path: '',//path代表储存emoji相关信息的json文件
icons: {},//icons储存着详细的emoji名称(转义后),以及图片的名字
defaults: {
button: null,
buttonLabel: 'Emojis',
buttonPosition: 'after'
}
};
$.fn.emojiarea = function(options) {
//extend方法用于合并参数到{},后面覆盖前面(例如options覆盖 $.emojiarea.defaults部分内容)
options = $.extend({}, $.emojiarea.defaults, options);
return this.each(function() {
var $textarea = $(this);
if ('contentEditable' in document.body && options.wysiwyg !== false) { //表示可编辑属性是否在document.body里
new EmojiArea_WYSIWYG($textarea, options);//将$textarea属性传入EmojiArea_WYSIWYG函数,构造一个emoji输入框对象
} else {
new EmojiArea_Plain($textarea, options);
}
});
};
(函数/对象)EmojiArea_WYSIWYG
var EmojiArea_WYSIWYG = function($textarea, options) {
var self = this;
CONST = this;
this.options = options;
this.$textarea = $textarea;
this.$editor = $('<div>').addClass('emoji-wysiwyg-editor');//editor就是代替了textarea的一个聊天框,它与$textarea绑定
this.$editor.text($textarea.val());
this.$editor.attr({contenteditable: 'true'});//contenteditable: 'true'属性的设置极为重要,它使得div变成可编辑状态,例如编辑文字,复制图片(下一章会讲)
this.$editor.on('blur keyup paste', function() { return self.onChange.apply(self, arguments); });//onChange方法用以editor和textarea之间的内容更新
this.$editor.on('mousedown focus', function() { document.execCommand('enableObjectResizing', false, false); });
this.$editor.on('blur', function() { document.execCommand('enableObjectResizing', true, true); });
var html = this.$editor.text();
var emojis = $.emojiarea.icons;
for (var key in emojis) {
if (emojis.hasOwnProperty(key)) {
html = html.replace(new RegExp(util.escapeRegex(key), 'g'), EmojiArea.createIcon(key));
}
}//遍历emojis,其中escapeRegex方法用于通过替换为转义码来转义最小的元字符集(\、*、+、?、|、{、[、(、)、^、$、.、# 和空白)
//createIcon通过key创建一个<img>替换:iconname:形式的表情(在textarea中,:iconname:代表一个表情)
this.$editor.html(html);
$textarea.hide().after(this.$editor);
this.setup();
this.$button.on('mousedown', function() {
if (self.hasFocus) {
self.selection = util.saveSelection();
}
});
};
editor中对鼠标划取部分的操作
util.replaceSelection = (function() {
if (window.getSelection) {//如果浏览器支持window.getSelection就使用这个方法,否则就用document.selection
return function(content) {
// 获取选定对象
var range, sel = window.getSelection();
var node = typeof content === 'string' ? document.createTextNode(content) : content;
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);//设置光标对象,把选中的文字转化为range对象,可以进行操作。接受一个参数,一般填写为0,表示从selection对象从0开始进行转化;
range.deleteContents();
range.insertNode(document.createTextNode(' '));
range.insertNode(node);
range.setStart(node, 0);//光标位置定位在表情节点开始位置,第一个参数为这个range对象的container,第2个参数为索引值,可以指定选择某段文字从哪开始
window.setTimeout(function() {
range = document.createRange();//selection创建
range.setStartAfter(node);
range.collapse(true);// 使光标开始和光标结束重叠
sel.removeAllRanges();// 清除选定对象的所有光标对象
sel.addRange(range);// 插入新的光标对象
}, 0);
}
}
} else if (document.selection && document.selection.createRange) {
return function(content) {
var range = document.selection.createRange();
if (typeof content === 'string') {
range.text = content;
} else {
range.pasteHTML(content.outerHTML);
}
}
}
})();
util.restoreSelection = (function() {//用于加载editor中的光标
if (window.getSelection) {
return function(savedSelection) {
var sel = window.getSelection();
sel.removeAllRanges();
for (var i = 0, len = savedSelection.length; i < len; ++i) {
sel.addRange(savedSelection[i]);
}
};
} else if (document.selection && document.selection.createRange) {
return function(savedSelection) {
if (savedSelection) {
savedSelection.select();
}
};
}
})();