在最近開發(fā)的IM中师郑,QA測(cè)出了一個(gè)BUG环葵,使用中文輸入法輸入@時(shí),不會(huì)彈出待選列表宝冕,但是英文輸入法就可以张遭,很奇怪,打開調(diào)試工具一看才知道原來(lái)在jquery的keydown事件中猬仁,獲取到的keyCode的值為229帝璧,并非所期待的值先誉。
PS: IM使用Electron框架開發(fā),在輸入框中輸入@時(shí)的烁,會(huì)彈出可以@的人的列表
代碼是這樣的:
// 監(jiān)聽(tīng)輸入框的鍵盤事件
$('#chat-input-area').keydown(function (e) {
if (e.key == '@') {
// 邏輯處理...
}
});
網(wǎng)上搜索了好多方案褐耳,結(jié)果都不行,這個(gè)問(wèn)題貌似無(wú)解啊渴庆,原因呢铃芦,好像是因?yàn)橹形妮斎敕ㄟ€在處理,會(huì)給調(diào)用者先返回一個(gè)值襟雷,但是js中接收了值就不會(huì)再處理了刃滓,所以中文輸入法下拿到的keyCode全部都是229,既然網(wǎng)上沒(méi)有好的方案耸弄,那只能采用最笨的方法了咧虎。
每次輸入記錄下輸入框中的值,再次輸入時(shí)拿當(dāng)前的值和上次記錄的值做diff计呈,然后拿到差異砰诵,也就是最后輸入的數(shù)據(jù)了,但是這個(gè)diff算法的效率成了關(guān)鍵了捌显,一個(gè)字符一個(gè)字符的比對(duì)茁彭,那效率肯定不高了,拿到當(dāng)前焦點(diǎn)的索引扶歪,然后減1理肺,就可以得到最后的輸入字符,但是獲取當(dāng)前的索引還是比較復(fù)雜的善镰,尤其是輸入框里可能會(huì)有表情等特殊字符妹萨,所以一向比較懶的我選擇了diff方案:
用到了這個(gè)開源庫(kù),diff速度很快:
https://github.com/jhchen/fast-diff
下面是部分代碼:
const diff = require('fast-diff');
let inputContent = '';
// 監(jiān)聽(tīng)輸入框的鍵盤事件
$('#chat-input-area').on('input', function (e) {
let innerText = $('#chat-input-area')[0].innerText;
let d = diff(inputContent, innerText);
// console.log('diff result = ', d);
inputContent = innerText;
let isAt = false;
if (!empty(d)) {
for (let i = 0; i < d.length; i++) {
if (d[i][0] == diff.INSERT && d[i][1].trimLeft(' ') == '@') {
isAt = true;
break;
}
}
}
if (!isAt) {
return;
}
// 處理@
// ...
});
經(jīng)測(cè)試媳禁,3k+的一篇文章copy進(jìn)去眠副,然后按下Shift + 2,@彈窗基本上是秒開竣稽,根本感覺(jué)不到慢囱怕,效率還可以。