自定義短信模板,要求:可以插入關鍵字,當然是可以在點擊到文本域中的任意位置畴嘶,關鍵字以中括號包裹的形式出現(xiàn)【關鍵字】,刪除關鍵字要整個關鍵都刪掉集晚,而不是自己全刪除窗悯。
效果圖
這里說下我的思路,要完成這樣一個功能,分為以下幾點:
1.在指定位置插入關鍵字
2.刪除關鍵字要整個刪除掉偷拔,并且關鍵字是不可編輯的,用戶也是不可以輸入中文中括號的
首先我們列一下難點
1.在任意位置插入蒋院,那肯定要拿到位置坐標,如果獲取這個位置莲绰?
2.關鍵字是用中文中括號包裹的欺旧,那么用戶就不可以去使用中文中括號,怎么阻止用戶輸入呢蛤签?
3.既然是關鍵字自然是不可以編輯的辞友,怎么讓它不可編輯?
4.中文中括號可英文中括號keyCode是一樣的震肮,怎么處理称龙?
5.當編輯區(qū)域失去焦點的時候,我們立即點關鍵字肯定就是要插入戳晌,但是點擊其他地方怎么處理鲫尊?
6.刪除關鍵字的時候,如何一次按鍵就整個都刪掉沦偎?
現(xiàn)在我們來把上面的難點一一解答
1.關于光標位置马昨,我上一篇文章中有寫到竞帽,這里就不多說了,http://www.reibang.com/p/19a507cd5fd7.
2.關于第2,3,4一起來說鸿捧。首先為了防止我們識別關鍵字出問題屹篓,那么就要阻止用戶自己輸入中括號,說道阻止輸入某個字符匙奴,大家很容想到堆巧,那就是在輸入的瞬間就把它刪除掉,這個沒錯泼菌。我們在判斷按鍵為左中括號時候去刪除的時候谍肤,會發(fā)現(xiàn)并不能完成整個中括號的刪除,因為落下一個右中括號哗伯。沒錯荒揣,第一個坑出現(xiàn)了,這是為什么焊刹,大家有沒有注意到系任,每次你輸入中文中括號的時候,其實只需要按左邊中括號就會左右都出現(xiàn)虐块,大括號小括號都是這樣俩滥。
【】按下左,左右一起出現(xiàn)
好贺奠,我們知道了問題所在霜旧,那就在右括號按下的時候刪掉兩個字符,可是儡率,你會發(fā)現(xiàn)挂据,如果只按右中括號的時候,他就真的只出現(xiàn)右中括號儿普,所以呢崎逃,分開處理。
這次沒問題了吧箕肃,可是你會發(fā)現(xiàn)依然是剩下右邊的括號沒刪除,而且還把前面的括號前的一個字符刪掉了今魔,坑吧勺像?這就是第二個坑,你在判斷keyCode的時候其實會有三次错森,第一次是左中括號keyCode吟宦,第二次是右中括號,第三次是左箭頭涩维。而第二次第三次并不是你按下的殃姓,是第一按下之后自動帶出的袁波。所以當你按下左中括號之后,其實最后光標是跑到了括號中蜗侈。
【|】
obj.addEventListener('keyup', function(e) {
//每次在文本域中輸入的時候都要獲取其光標位置篷牌,以便于其他操作
cursorIndex = getFocus(obj);
//由于我們是禁止輸入中文中括號的,而中文中括號輸入左右情況不同踏幻,需要分別處理
if (e.keyCode == 219) {
e.preventDefault();
//這里獲取到光標左側的內(nèi)容
var leftChar = obj.value.slice(cursorIndex - 1, cursorIndex);
//只有輸入結束的是右中括號枷颊,而且它的前一個字符是左中括號才把它刪除,防止把關鍵字刪除掉
if (/\】/g.test(leftChar) && obj.value.charAt(cursorIndex - 2) === '【') {
obj.value = obj.value.slice(0, cursorIndex - 2) + obj.value.slice(cursorIndex, obj.value.length);
}
} else if (e.keyCode == 221) {
e.preventDefault();
//右中括號就好辦多了该面,因為它不會自動帶出左中括號
var leftChar = obj.value.slice(cursorIndex - 1, cursorIndex);
if (/\】/g.test(leftChar)) {
obj.value = obj.value.slice(0, cursorIndex - 1) + obj.value.slice(cursorIndex, obj.value.length);
}
}
//防止上下左右鍵移動光標進入關鍵字中
if ((e.keyCode == 37 || e.keyCode == 39 || e.keyCode == 38 || e.keyCode == 40) && lastKeyCode !== 219) {
dealFocusMove(obj, cursorIndex);
} else if (e.keyCode == 8) {
//backspace刪除的時候刪除整個關鍵字
dealFocusL(obj, cursorIndex, allKeyWords);
} else if (e.keyCode == 46) {
//delete刪除的時候也是刪除整個關鍵字
dealFocusR(obj, cursorIndex, allKeyWords)
}
if (e.keyCode !== 37 && e.keyCode !== 39) {
//這里防止手動按得左右鍵影響左中括號判斷
lastKeyCode = e.keyCode;
}
}, false);
那這咋搞夭苗,還要分別刪除么?不用的隔缀,我們只要不讓他跑到中間就可以了题造,對就是preventDefault()。有疑問了吧猾瘸?沒錯界赔,這個無法阻止中文按鍵。
關鍵字不可編輯须妻,但是文本怎么能不編輯白序颉?編輯的關鍵是什么荒吏,就是有光標啊敛惊,那我們不讓光標進入關鍵字不就行了,這里還順帶解決了的防止鼠標點擊關鍵字中間绰更。我想的思路是瞧挤,關鍵字的中括號是成對出現(xiàn)的,那么光標進入了儡湾,光標前面的內(nèi)容中中括號自然不是成對的特恬,這就是判斷條件,把它挪出來就可以了徐钠。當然從按左右鍵要分別處理癌刽,因為是向不同方向越過整個關鍵字,上下鍵就簡單了尝丐,都放把光標設置在關鍵字左邊就可以了显拜。
if ((e.keyCode == 37 || e.keyCode == 39) && lastKeyCode === 219) {
//這里是防止按下中文中括號左鍵的時候帶動左右鍵的按下,這樣保證光標一直在最后
e.preventDefault();
}
3.怎么處理點擊文本域爹袁,立即點擊關鍵字是插入远荠,點擊其他地方之后再點擊關鍵字不可插入?這里我定義了一個參數(shù)存儲光標位置失息,當點擊其他位置的時候就讓光標置空譬淳,而點擊關鍵字的時候判斷一下光標位置是否存在就可以了
if (cursorIndex !== null) {
//這里判斷是否是我們要點擊的是不是關鍵字
if (e.target.tagName !== "TEXTAREA" && e.target.getAttribute('isFocus')) {
//插入關鍵字
} else if (e.target.tagName == "TEXTAREA" && e.target.getAttribute('isFocus')) {
//點擊文本區(qū)域操作
} else {
//點擊其他地方要將光標位置置空档址,防止點擊關鍵字添加
cursorIndex = null;
}
}
4.刪除整個關鍵字,這里還是用關于如何防止光標進入關鍵字的方式邻梆。只要發(fā)現(xiàn)不成對守伸,就把最近的另一半到光標之間的刪除
【關鍵字| 或者 |關鍵字】
就是backspace和delete兩種,當然在處理的時候用了一些小技巧确虱,就是正則表達式的RegExp.lastIndex,最后一次匹配到的位置含友,還有其他,看代碼吧校辩。