前言:html
因爲公司開發項目須要用到表情插件,在網上百度了很久,不少表情插件,都是須要引用好多js文件,也沒有現成的demo可使用,還有一些插件是引用好多圖片,每個表情都要從新請求一下。爲了這樣一個功能,要引入好多js,img,也是得不償失……前端
因此,博主本身碼了一個小巧的「表情插件」,方便之後項目直接使用。jquery
demo 地址:http://121.42.190.17/demo/emoji/src/demo.htmlgit
功能github
功能:傳遞表情對應的字符格式到後臺,後臺返回字符串,前端將該字符串解析展現成相應的表情展現在頁面上。數組
使用方法:安全
在option中配置須要的參數服務器
var option = { emojiArray: ['angry'], //填寫表情字符串的數組,【注:源文件image下面的圖標,只須要寫紅框內的字符串,詳見下圖】 textareaId: 'emoji-editor', //輸入框的id loadId: 'load', //加載表情的id emojiContainer: 'emojiContainer', //存儲表情的容器對象 sendId: 'send', //發送信息的按鈕 id emojiTranslateCls:'emoji-comment', //須要轉換成表情(img)的容器類名,只須要添加一個類,便可自動將:kissing_heart:渲染成表情~ }; /*調用方法*/ var text = new Emoji(option); text.init();
大體效果截圖:(ui方面能夠根據各自須要進行美化)app
點擊發送後,發送給後臺的數據是:ide
表情插件的三個原理:
如何顯示錶情?
CSS Sprites(圖片整合技術),先設定好背景圖標,而後定義每個小圖標的position,width,height,便可顯示想要顯示的表情。
期間遇到的問題:如何控制顯示錶情的大小?
首先想到的是background-size這個方法,可是要從新定義它的position,很是耗費「體力」,後來,柳暗花明,發現一個屬性transform: scale(1.5); 控制當前元素縮放比率,哈哈,一行代碼就搞定啦~想要表情大,仍是小,尺寸不滿意?統統一行代碼搞定
如何在輸入框中顯示錶情圖標?
一開始是選擇 input 的textarea,可是,將表情img 「append」到這個輸入框後面,也沒有顯示出這個圖標,後來嘗試了div,再「append」以後,發現可以成功顯示錶情,可是div又不能輸入文字,無果……
初步想法:使用input監聽,將textarea值實時加到div中,一樣的,這個也是費力不討好~繼續探索……
後來發現一個很大衆的屬性。contenteditable=」true」,又愉快的選擇了contenteditable。
一開始是用span承載表情圖標,可是用div或者span標籤放置圖像,則contenteditable會默認加到最後的div/span中……,因此會致使輸入表情圖標後,再輸入文字,最後的文字會在最後一個div/span中,致使沒有顯示文字。好吧……真是心累……
既然div/span 不能夠,就使用img標籤承載表情,這下終於可以正常輸入了。
【contenteditable有一個問題,它支持富文本,不安全,並且用戶體驗很差。】
好比:用戶粘貼的時候,會自動帶格式,例子以下:
這邊是採用網上大神的一段代碼,去除掉富文本功能,具體參考:某大神博文
如何對圖片和文字進行轉換?
這時候就要使用強大的正則了,先用html()獲取內容,再對內容進行處理。
轉換成文字:
content.replace(/<img\b[^>]*/, imgObj[j]) //匹配全部的<img />,替換成相應的格式 imgObj.push(format + img[i].getAttribute("alt") + format); //這裏的format我使用的是: 因此就是相似這樣 :fearful: 的格式
轉換成圖片:
var keys = '\\+1|-1|100|109|1234|8ball|a|ab|abc|abcd|accept……' //這裏只列出部分 regex = new RegExp(':(' + keys + '):', 'g'), // 匹配格式形如這樣子的格式 :100: $(obj[i]).html().replace(regex, emoji) //替換 function emoji() { var key = arguments[1]; return '<img src="" alt="' + key + '"class="emoji emoji_' + key + '"/>'; //返回對應的img格式 }
整個插件的代碼格式,也是比較常見的封裝方式
//Emoji對象可變的屬性 function Emoji(option) { this.emoji = option.emojiArray, this.textareaId = option.textareaId, this.loadId = option.loadId, this.sendId = option.sendId, this.emojiContainer = option.emojiContainer, this.emojiTranslateCls = option.emojiTranslateCls; }
//每一次生成一個實例,上面的屬性都會從新生成一次,這樣對於固定的方法,會多佔用一些內存。這樣既不環保,也缺少效率。因此能夠把那些不變的屬性和方法,直接定義在prototype對象上。這時全部固定的方法,其實都是同一個內存地址,指向prototype對象,所以就提升了運行效率。
Emoji.prototype = { init: function () { //放一些初始化的方法 this.toEmoji(); this.loadEmoji(); this.bindEvent(); }, bindEvent: function () {}, toEmoji: function () {}, //服務器數據轉換成表情 toText: function () {} //轉換成文字 loadEmoji: function () {} //加載表情 }
好啦,這樣一個表情插件就算完工了,系不繫很簡單?目前暫時須要依賴jquery,以後若是有精力的話繼續搗鼓一個基於原生js的O(∩_∩)O,具體的實現代碼在github上。
最後,附上github地址:https://github.com/beidan/emoji 歡迎star,fork~~~