這幾天有個工作需求,就是在富文本輸入區域(kindeditor)可以有@功能,能夠容易提示用戶名的(像在qq群組@人一樣)。在網上找了一個叫bootstrap-suggest的插件,卻不能滿足我的需求,於是我決定在該插件上改良,主要是下面幾點:
1. @內容的輸入,能夠匹配多個屬性值。
2. 選中列表值後,是成塊插入kindeditor的(方便刪除,也利於區分文本)。
3. 修正輸入偶數關鍵字@功能失效問題。
前言
在一開始,我用bootstrap-suggest(https://github.com/lodev09/bootstrap-suggest),這個插件能夠實現以下效果。
但是我發覺有幾個問題:
1. 只能單一匹配(可能存在需要匹配拼音或中文)。
2. 偶數位的@功能會失效。
3. 選取值後,只是簡單文本(沒有qq一樣那種成塊效果)。
jquery-kindeditor-suggest
由於我不想重復造輪子,於是決定在上面插件做調整,以滿足我的需求,有幾個關鍵地方需說明。
1. startOffset取值錯誤問題。
如果使用了KindEditor的insertHTML,會導致下一次startOffset取值出錯。原插件在獲取光標位置(top,left)時,會需要插入一個span去獲取,在獲取完後刪除,但是這時候下一次editor.cmd.range.startOffset;就出錯。
於是我修改了插入的方式:
var doc = editor.cmd.range.doc, range = editor.cmd.range, frag = doc.createDocumentFragment(); KindEditor('@<span id="input-textarea-caret-position-mirror-span">.</span>' , doc).each(function() { frag.appendChild(this); }); range.deleteContents(); range.insertNode(frag); range.collapse(false);
PS:在170行。
2. 替換選擇值
將@後面的輸入內容刪除(包含@),然後插入一個完整的標簽(選擇值),還要保證光標位置正確。
var dType = !!el.cmd.range.startContainer.data ? "data" : "innerHTML"; //這個取值最關鍵 var sVal = el.cmd.range.startContainer[dType]; var lAt = sVal.lastIndexOf(this.key); el.cmd.range.startContainer[dType] = sVal.substring(0, lAt) ; el.insertHtml("<span contenteditable='false'>"+this.key+item.value+' </span>' +'<span id="input-textarea-caret-position-mirror-span">.</span>'); var span = el.edit.doc .getElementById('input-textarea-caret-position-mirror-span'); var range = el.edit.doc.createRange(); range.selectNodeContents(span); range.collapse(false); var sel = el.edit.win.getSelection(); sel.removeAllRanges(); sel.addRange(range); //hack:修正下一次startOffset span.parentNode.removeChild(span);
PS:在442行。
修改後效果
內容是富文本輸入區域,插入的成塊文本。
總結
雖然是基於他人的插件,但我在修復問題上也花費了很多心思,之前一直發現沒有精確針對kindeditord @功能的插件,所以我就自己弄了下。
我把源代碼放在Github上了,有需要的可去下:https://github.com/codingforme/jquery-kindeditor-suggest
以上所述是小編給大家介紹的jQuery彈出下拉列表插件(實現kindeditor的@功能),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家的支持!