閱讀全文你將獲得以下解決方案。
以下實例代碼執行環境為Chrome80
方案一
HTML5 Textarea 元素
1. 自動獲得焦點
點擊編輯自動獲得焦點后光標跳轉到了最前面,why?

查文檔 MDN,textarea元素存在selectionEnd和selectionStart的屬性用來表示選中的文本開始位置和結束位置,DOM接口實例是 HTMLTextAreaElement, 它具有 setSelectionRange 方法,用來選中輸入框中的文本,用法:TextAreaElement.setSelectionRange(selectionStart, selectionEnd, [optional] selectionDirection);
那么我們只要做到selectionStart === selectionEnd === value.length , 這樣光標就選中到最末尾。
edit.addEventListener("click", function() { txt.classList.add("hidden"); document.body.insertBefore(textarea, edit); textarea.innerHTML = "這是需要編輯的信息"; textarea.focus(); // textarea.selectionEnd = textarea.innerHTML.length; textarea.setSelectionRange( textarea.innerHTML.length, textarea.innerHTML.length );});2. 自適應高度
當不設置高度時換行會出現滾動條,所以只要讓textarea滾動條消失,讓其height = scrollHieght, 那么如何監聽textarea的變化,則需要input事件,讓textarea高度動態等于它的scrollHeight即可,代碼如下:
textarea.addEventListener("input", function() { this.style.height = `${this.scrollHeight}px`;});
為什么每次輸入都會使得高度增加(每次增加4px),經過測試Safari同樣也是這個效果,Firefox符合預期高度不異常增加,查看Chrome控制臺發現textarea內置了很多樣式,嘗試將去掉padding后,可以正常隨著內容增加高度自適應了。
<style>textarea { padding: 0;}</style><textarea></textarea><script>const textarea = document.createElement("textarea");textarea.addEventListener("input", function(e) { this.style.height = `${this.scrollHeight}px`;});</script>為什么去掉padding值,輸入后高度就不增加了?(未找到合理的解釋,歡迎留言討論解答)
但是刪除文本的情況下height并未能自動縮放,分析原因, 當刪除文本換行的時候scrollHeight的大小并未發生改變,scrollHeight作為只讀屬性( MDN-文檔),如何讓scrollHeight高度重新計算哪?只有改變高度,于是:
textarea.addEventListener("input", function(e) { this.style.height = "inherit"; this.style.height = `${this.scrollHeight}px`;});到此高度自適應輸入內容完成,但是每次換行的閃動很難受,transition走一波,
textarea { overflow: hidden; // 防止換行出現滾動條閃動 padding: 5px 10px; box-sizing: border-box; transition: all 0.2s linear;}結果transition并沒效果,原因height初始值或者參考值必須為數值過渡動畫才會生效,height設置為auto或者inherit動畫不會生效, 所以折中的辦法就是當刪除的時候重新重置高度,輸入時不需要重置,這樣輸入時動畫生效, 刪除沒有動畫, 暫時沒想到更好的辦法。
textarea.addEventListener("keyup", function(e) { if (e.keyCode === 8) { this.style.height = "inherit"; this.style.height = `${this.scrollHeight}px`; } else { this.style.height = `${this.scrollHeight}px`; }});3. 支持粘貼文本,圖片等
textarea只能輸入文本,無法實現粘貼圖片。
textarea.addEventListener( "paste", function(e) { e.preventDefault(); console.log( "paste", e.clipboardData.items, e.clipboardData.types, e.clipboardData.getData("text/html"), e.clipboardData.getData("text/plain"), e.clipboardData.getData("text/Files") ); }, false);方案二
div contenteditable 替換textarea
1. 自動獲得焦點
編輯div contenteditable為true,然后利用Range和Selection 光標移動到最后的效果。
edit.addEventListener("click", () => { textarea.setAttribute("contenteditable", true); textarea.focus(); const range = document.createRange(); // range 包含的內容 range.selectNodeContents(textarea); // range.setStart(textarea.firstChild, 0); // range.setStart(textarea.lastChild, textarea.innerHTML.length); // 起始位置是否相同 range.collapse(false); const sel = window.getSelection(); // 將所有的區域都從選區中移除。 sel.removeAllRanges(); // 一個區域(Range)對象將被加入選區。 sel.addRange(range);});2. 自適應高度
div contenteditable 天然支持根據輸入來自適應高度。
3. 粘貼圖片, 文本等
textarea.addEventListener("paste", function(e) { e.preventDefault(); const clipboardData = e.clipboardData || e.originalEvent.clipboardData; // 獲取純文本 let text = clipboardData.getData("text/plain"); let file = clipboardData.getData("text/plain"); // console.log(clipboardData.items, clipboardData.getData("text/Files")); // 插入img,可以做一些上傳圖片的一些操作 insertImg(clipboardData); // 只輸入純文本 document.execCommand("insertText", false, text);});此方法可以限定只能上傳文本或者圖片。
歡迎留言討論其他textarea高度自適應的方案。
到此這篇關于HTML5 textarea高度自適應的兩種方案的文章就介紹到這了,更多相關textarea高度自適應內容請搜索武林網以前的文章或繼續瀏覽下面的相關文章,希望大家以后多多支持武林網!
新聞熱點
疑難解答