Node.js——微信emoji功能的實(shí)現(xiàn)

一個(gè)非常好用的emoji插件

jquery-emojiarea-master

如何利用該插件迅速搭建搭建emoji界面?

在主布局文件下寫(xiě)下如下代碼

<script>
    var $wysiwyg = $('.emojis-wysiwyg').emojiarea({wysiwyg: true,button: '.showemoji'});
    //button: '.showemoji' 則是用于自定義打開(kāi)emoji選擇界面的按鈕的樣式
    //emojis-wysiwyg則是textarea對(duì)應(yīng)的class,該操作用于創(chuàng)建一個(gè)div與我們的textarea綁定
</script>

分析源碼

jquery-emojiarea.js

數(shù)據(jù)存儲(chǔ)與emojiarea構(gòu)造方法
    //$.fx是類級(jí)別的插件開(kāi)發(fā),即給jQuery添加新的全局函數(shù)
    $.emojiarea = {
        path: '',//path代表儲(chǔ)存emoji相關(guān)信息的json文件
        icons: {},//icons儲(chǔ)存著詳細(xì)的emoji名稱(轉(zhuǎn)義后),以及圖片的名字
        defaults: {
            button: null,
            buttonLabel: 'Emojis',
            buttonPosition: 'after'
        }
    };
    $.fn.emojiarea = function(options) {
        //extend方法用于合并參數(shù)到{},后面覆蓋前面(例如options覆蓋 $.emojiarea.defaults部分內(nèi)容)
        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函數(shù),構(gòu)造一個(gè)emoji輸入框?qū)ο?            } else {
                new EmojiArea_Plain($textarea, options);
            }
        });
    };
(函數(shù)/對(duì)象)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的一個(gè)聊天框,它與$textarea綁定
        this.$editor.text($textarea.val());
        this.$editor.attr({contenteditable: 'true'});//contenteditable: 'true'屬性的設(shè)置極為重要,它使得div變成可編輯狀態(tài),例如編輯文字,復(fù)制圖片(下一章會(huì)講)
        this.$editor.on('blur keyup paste', function() { return self.onChange.apply(self, arguments); });//onChange方法用以editor和textarea之間的內(nèi)容更新
        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方法用于通過(guò)替換為轉(zhuǎn)義碼來(lái)轉(zhuǎn)義最小的元字符集(\、*、+、?、|、{、[、(、)、^、$、.、# 和空白)
        //createIcon通過(guò)key創(chuàng)建一個(gè)<img>替換:iconname:形式的表情(在textarea中,:iconname:代表一個(gè)表情)
        this.$editor.html(html);

        $textarea.hide().after(this.$editor);

        this.setup();

        this.$button.on('mousedown', function() {
            if (self.hasFocus) {
                self.selection = util.saveSelection();
            }
        });
    };
editor中對(duì)鼠標(biāo)劃取部分的操作
util.replaceSelection = (function() {
        if (window.getSelection) {//如果瀏覽器支持window.getSelection就使用這個(gè)方法,否則就用document.selection
            return function(content) {
                // 獲取選定對(duì)象
                var range, sel = window.getSelection();
                var node = typeof content === 'string' ? document.createTextNode(content) : content;
                if (sel.getRangeAt && sel.rangeCount) {
                    range = sel.getRangeAt(0);//設(shè)置光標(biāo)對(duì)象,把選中的文字轉(zhuǎn)化為range對(duì)象,可以進(jìn)行操作。接受一個(gè)參數(shù),一般填寫(xiě)為0,表示從selection對(duì)象從0開(kāi)始進(jìn)行轉(zhuǎn)化;
                    range.deleteContents();
                    range.insertNode(document.createTextNode(' '));
                    range.insertNode(node);
                    range.setStart(node, 0);//光標(biāo)位置定位在表情節(jié)點(diǎn)開(kāi)始位置,第一個(gè)參數(shù)為這個(gè)range對(duì)象的container,第2個(gè)參數(shù)為索引值,可以指定選擇某段文字從哪開(kāi)始
                    
                    window.setTimeout(function() {
                        range = document.createRange();//selection創(chuàng)建
                        range.setStartAfter(node);
                        range.collapse(true);// 使光標(biāo)開(kāi)始和光標(biāo)結(jié)束重疊
                        sel.removeAllRanges();// 清除選定對(duì)象的所有光標(biāo)對(duì)象
                        sel.addRange(range);// 插入新的光標(biāo)對(duì)象
                    }, 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中的光標(biāo)
        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();
                }
            };
        }
    })();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容