前端社团

Node.js——微信emoji功能的实现

2016-10-29  本文已影响500人  折柳画马

一个非常好用的emoji插件

jquery-emojiarea-master

如何利用该插件迅速搭建搭建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();
                }
            };
        }
    })();
上一篇下一篇

猜你喜欢

热点阅读