閱讀全文你將得到如下解決方案。
textarea
,自動得到焦點如下實例代碼執行環境爲Chrome80
HTML5 Textarea 元素
點擊編輯自動得到焦點後光標跳轉到了最前面,why?
javascript
查文檔 MDN,textarea
元素存在selectionEnd
和selectionStart
的屬性用來表示選中的文本開始位置和結束位置,DOM接口實例是 HTMLTextAreaElement
, 它具備 setSelectionRange
方法,用來選中輸入框中的文本,用法:TextAreaElement.setSelectionRange(selectionStart, selectionEnd, [optional] selectionDirection);
css
那麼咱們只要作到selectionStart === selectionEnd === value.length
, 這樣光標就選中到最末尾。html
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 ); });
當不設置高度時換行會出現滾動條,因此只要讓textarea
滾動條消失,讓其height = scrollHieght
, 那麼如何監聽textarea的變化,則須要input
事件,讓textarea
高度動態等於它的scrollHeight
便可,代碼以下:java
textarea.addEventListener("input", function() { this.style.height = `${this.scrollHeight}px`; });
爲何每次輸入都會使得高度增長(每次增長4px),通過測試Safari
一樣也是這個效果,Firefox
符合預期高度不異常增長,查看Chrome控制檯發現(查看 chromium) 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
高度從新計算哪?只有改變高度,因而:this
textarea.addEventListener("input", function(e) { this.style.height = "inherit"; this.style.height = `${this.scrollHeight}px`; });
到此高度自適應輸入內容完成,可是每次換行的閃動很難受,transition
走一波,google
textarea { overflow: hidden; // 防止換行出現滾動條閃動 padding: 5px 10px; box-sizing: border-box; transition: all 0.2s linear; }
結果transition
並沒效果,緣由height
初始值或者參考值必須爲數值過渡動畫纔會生效,height
設置爲auto
或者inherit
動畫不會生效, 因此折中的辦法就是當刪除的時候從新重置高度,輸入時不須要重置,這樣輸入時動畫生效, 刪除沒有動畫, 暫時沒想到更好的辦法。spa
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`; } });
textarea只能輸入文本,沒法實現粘貼圖片。code
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
編輯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); });
div contenteditable
自然支持根據輸入來自適應高度。
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
高度是適應的方案。