筆者在公司的項目中需要開發一個自訂表格情模組如下:
其javascript問題實現如下:
/*** Emoji Module* @fileOverview emoji* @author Collin*//// <reference path="../jquery-1.7.2-vsdoc.js" />var emoji = { url: 'xxx', icons: ["/驚訝/", "/撇嘴/", "/色/", "/發獃/", "/得意/", "/流淚/", "/害羞/", "/閉嘴/", "/睡/", "/大哭/", "/尷尬/", "/發怒/", "/調皮/", "/呲牙/", "/微笑/", "/難過/", "/酷/", "/生病/", "/抓狂/", "/吐/", "/偷笑/", "/可愛/", "/白眼/", "/傲慢/", "/饑餓/", "/困/", "/驚恐/", "/流汗/", "/憨笑/", "/大兵/", "/奮鬥/", "/咒罵/", "/疑問/", "/噓/", "/暈/", "/折磨/", "/衰/", "/骷髏/", "/敲打/", "/再見/", "/豬/", "/貓/", "/狗/", "/擁抱/", "/錢/", "/燈泡/", "/冰激淩/", "/蛋糕/", "/閃電/", "/炸彈/", "/刀/", "/足球/", "/音符/", "/大便/", "/咖啡/", "/米飯/", "/藥/", "/玫瑰/", "/枯萎/", "/示愛/", "/心跳/", "/桌子/", "/握手/", "/禮物/", "/電話/", "/時鐘/", "/郵件/", "/電視/", "/太陽/", "/月亮/", "/強/", "/弱/", "/握手/", "/耶/", "/兔子/", "/美女/", "/小孩/", "/帥哥/", "/酒/", "/可樂/"], parse: function (content) { if (content == null || content == '') return; for (var i = 0; i < 80; i++) { var regex = new RegExp(this.icons[i], "g"); var img = "<img src=\"" + this.url + i + ".gif\" />"; content = content.replace(regex, img); } return content; }, setup: function (ctlOutput, ctlBind, ctlContainer, direction) { /*載入表情*/ var timeoutHandler = 0, allEmojis = '', borderClass = ''; for (var i = 0; i < 80; i++) { borderClass = ''; if (i % 10 == 9 && i != 0) borderClass = "emoji-right"; if (i > 69) borderClass = "emoji-bottom"; if (i == 79) borderClass = "emoji-bottom emoji-right"; allEmojis += "<div data-exta=\"" + this.icons[i] + "\" class=\"emoji " + borderClass + "\" style=\" background-image:url(" + this.url + i + ".gif);\"></div>"; } $(ctlContainer).html(allEmojis); $(ctlContainer).on("click", "div", null, function () { $(ctlOutput).val($(ctlOutput).val() + $(this).attr("data-exta")); //$(ctlOutput).focus(); $(ctlContainer).hide(); }); $(ctlBind).click(function () { switch (direction) { case "bottom": { $(ctlContainer).css({ position: 'absolute', bottom: (0 - $(ctlContainer).height()) + 'px', left: 0 }).show(); break; } case "top": { $(ctlContainer).css({ position: 'absolute', bottom: $(this).height()+"px", left: 0 }).show(); break; } } }).mouseleave(function () { timeoutHandler = window.setTimeout(function () { $(ctlContainer).hide(); }, 600); }); $(ctlContainer).mouseleave(function () { $(this).hide(); }).mouseover(function () { window.clearTimeout(timeoutHandler); }); }};
上述實現其parse方法時間複雜度過高, 在轉換大文本時會執行無效迴圈, 筆者在看javascript Regex 和 string.replace其正則替換支援回調處理匹配結果
reference:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace
改進後的parse 如下:
parse: function (content) { if (content == null || content == '') return; var regex = new RegExp(this.icons.join('|'), 'g'); var that = this; return content.replace(regex, function (match) { var index = that.icons.indexOf(match); if (index < 0) return match; return '<img src="' + that.url + index + '.gif" />' }); }