摘要:還沒結束上述例子中,在輸入框中表情只能以文本的形式呈現。如果想在輸入框中呈現輸入的表情,該怎么辦呢使用屬性為的容器代替是必須的,因為中只能顯示文本。
在普通的 textarea 中,只能顯示普通的文本。如果簡單的輸入文本,textarea 便足以勝任。但是實際情況往往要復雜得多。
簡單版本的插入表情常見的版本一般都是使用 textarea,然后表情使用某種約定的文本格式代替,比如“你好啊[微笑]”。在呈現的時候,通過固定的文本解析方法將內容中的表情文本替換成圖片。新浪微博中發微博的輸入框就是如此。但是,在這有一點需要注意,如果只是簡單的在文本的最后插入表情之類的預定好的文本格式,只需獲取到到 textarea 的 value 然后做加法即可。
let editor = document.querySelect("#editor"); editor.value += "[微笑]";沒你想的這么簡單
但實際情況卻沒有這么簡單,因為用戶可以自己選擇光標的位置。當用戶在某一段文本中間插入光標之后,可不是簡單的加法了。在這種情況下,需要獲取到光標所在位置,在這個位置上插入用來代替表情的文本,然后將光標設置到表情文本的后面。在這需要兩個額外的方法:getCaretPosition和 setCaretPosition 。
getCaretPosition/setCaretPosition瀏覽器并沒有提供直接獲取光標位置的方法,需要我們變通的處理。瀏覽器基本上都支持文本框的select()方法,這個方法用于選中文本框中所有的文本,但是只能乖乖的拿到返回的所有文本。HTML5 添加了兩個屬性:selectionStart 和 selectionEnd 幫助我們更加順利地獲取選擇的文本。這兩個屬性中保存的是基于0的數值,表示所選擇的文本的范圍,分別表示文本選區(選中的文本)開頭和結尾相對整個文本內容的偏移量(在整個文本內容中的位置)。例如:
let editor = document.querySelector("#editor"); // 從第一個字符開始,選中三個字符 editor.selectionStart = 0; editor.selectionEnd = 1; // 從第三個字符開始選中三個字符 editor.selectionStart = 2; editor.selectionEnd = 5;
說到這你可能要問了,這個光標有啥關系啊?別急,聽我慢慢說。既然上述兩個設置不同數字可以選擇文本,那如果兩個值設置成相同的數字,會怎么樣呢?
// 從第三個字符開始選中零個字符 editor.selectionStart = 2; editor.selectionEnd = 2;
起點和終點重合了!那么換個角度來描述就是:當我們在獲取光標位置的時候,其實就是選中的文本范圍起點和重點重合,相當于文本范圍的起點偏移量其實就是光標所在的位置偏移量,所以此時selectionStart的返回值就是我們需要的結果。
更關鍵的是,當 End 和 Start 設置成相同值時,選區也是空的,起點和重點充電,就好像是設置了光標的位置。其實有一個簡便的方法 setSelectionRange(start, end),原理相同。
當然有興趣你也可以試試 End小于 Start的情況。上述這些在現代瀏覽器和 IE9+ 上都支持。
前端向來麻煩的還是瀏覽器的兼容問題。在低版本的 IE 中只能使用 document.selection 對象來模擬光標定位了。document.selection 只存在于 IE8 及更早的版本(可以使用 window.getSelection 代替),保存著用戶在整個文檔范圍內選擇的文本信息,但是無法確定用戶選擇的是頁面中哪個部位的文本。要想取得選擇的文本,首先需要創建一個范圍(Range,IE9+ 支持 DOM Range API,但是 IE8及之前的版本不支持,但是有類似的概念,text range。這是 IE 專有的特性)。可使用 document.selection.createTextRange 來創建我們所需要的 text range。然后利用moveStart().aspx)將文本的范圍的起點從當前位置(當前位置起點和重點是重合的)移動到文本的開頭,然后計算選中文本的長度,這個長度值可以用來代替當前光標的位置。
let range = document.selection.createRange(); range.moveStart("character", editor.value.length); cursurPosition = range.text.length;
設置光標位置思路類似,但是代碼稍有不同:
let range = editor.createTextRange(); range.collapse(true); range.moveEnd("character", pos); range.moveStart("character", pos); range.select();
總的來說,在 textarea 中獲取和設置光標位置還是蠻簡單的。講到這里了,我想插入表情應該是很輕松的一件事情了
獲取光標位置(文本范圍前后重疊) -> 修改文本范圍(或者手動拼接) -> 重新設置光標位置
至此,表情插入功能的基本實現。
還沒結束上述例子中,在輸入框中表情只能以文本的形式呈現。如果想在輸入框中呈現輸入的表情,該怎么辦呢?使用 contenteditable 屬性為 true 的容器代替 textarea 是必須的,因為 textarea 中只能顯示文本。但是這就足夠了嗎?不,顯然不夠。沒有了 textarea 則以為這沒有了 setSelectionRange, selectionStart 和 selectionEnd。但是好在原理也是類似,依舊使用 Range API 或者 Text Range(IE8及其更低版本)。具體的可以參考這篇:html元素contenteditable屬性如何定位光標和設置光標和這篇在可編輯的div中插入圖片。 具體實現代碼我就不貼了,大家可以自己思考捋一捋。舉一反三,如果你真真正正地知道如何正確插入圖片,那么插入復雜的 DOM 結構對你來說也是輕而易舉。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87840.html
摘要:由于我們的富文本輸入框比較簡單,所以只需要處理兩類數據即可,其一是普通的文本類型數據,包括表情其二則是圖片類型數據。 最近折騰 Websocket,打算開發一個聊天室應用練練手。在應用開發的過程中發現可以插入 emoji ,粘貼圖片的富文本輸入框其實蘊含著許多有趣的知識,于是便打算記錄下來和大家分享。 倉庫地址:chat-input-box預覽地址:https://codepen.io...
摘要:背景最近我們微信讀書將寫想法換成了基于的富文本編輯器,遇到了不少問題,這里我將簡單的介紹一下我們在開發過程中踩到的坑。 背景 最近我們微信讀書將寫想法換成了基于webview的富文本編輯器,遇到了不少問題,這里我將簡單的介紹一下我們在開發過程中踩到的坑。 實現富文本編輯器有兩個基本思路: 基于native實現:比如coretext或者textkit 基于uiwebview實現 第一...
摘要:技術棧項目背景這個項目主要是為了玩玩,項目的方向大概是做出類似的在線聊天系統。項目使用進行部署和管理,功能在不斷的迭代開發中。首頁用戶列表用戶中心注冊登陸注銷用戶資料指定聊天室開始安裝使用之前,請在中修改的安裝路徑。 技術棧:NodeJS & SocketIO & Express & EJS & MongoDB & Gulp 項目背景 這個項目主要是為了玩玩NodeJS,項目的方向大概...
摘要:技術棧項目背景這個項目主要是為了玩玩,項目的方向大概是做出類似的在線聊天系統。項目使用進行部署和管理,功能在不斷的迭代開發中。首頁用戶列表用戶中心注冊登陸注銷用戶資料指定聊天室開始安裝使用之前,請在中修改的安裝路徑。 技術棧:NodeJS & SocketIO & Express & EJS & MongoDB & Gulp 項目背景 這個項目主要是為了玩玩NodeJS,項目的方向大概...
閱讀 2146·2021-10-12 10:11
閱讀 846·2021-10-09 09:41
閱讀 3760·2021-09-09 11:37
閱讀 1940·2021-09-08 10:41
閱讀 2641·2019-08-30 12:58
閱讀 2373·2019-08-30 10:58
閱讀 1278·2019-08-26 13:40
閱讀 4113·2019-08-26 13:36