日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

编写自适应高度的 textarea

發布時間:2024/4/13 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 编写自适应高度的 textarea 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文本框是很常見的輸入控件,我相信只要寫過表單的肯定接觸過 textarea 這個元素。

OK。但是現在產品經理說了:需要這個文本框可以根據用戶輸入內容自適應其高度。

height: auto

有些初學者可能會想:自適應高度不就是 height: auto 么?可是你想一下,一個 textarea 沒有手工給它指定過樣式,不應該就默認是 height: auto 么?但是它還是有自己的初始高度,并沒有像一個 div 那樣高度為 0。

與 div 不同,textarea 的默認高度不是根據其內容自適應,而是由屬性 rows 指定,其默認值是 2。rows 這個屬性(Attribute)只接受正整數,指定其他值瀏覽器會忽略掉其值,比如你寫 rows="auto" 那么 rows 就是 2,rows="0" 也是 2。

所以指定 height: auto 是行不通的,height 屬性必須人工指定其值。

scrollHeight

遇到過這個問題的同學(比如當初的筆者),肯定想到過 scrollHeight 這個 DOM 屬性。想法很簡單,當用戶輸入的文本超過了文本框自身高度時不是會出現滾動條嘛,那么自然而然就能想到 scrollHeight 這個屬性。scrollHeight 就應該是用戶輸入文本的真實高度,至少超過文本框既定高度時是這樣。

那么問題來了:如果沒超過呢?

OK 我知道你會先指定 rows="1" 讓文本框默認高度只有一行。但是考慮這種情況:用戶先輸入了很多行文本

然后刪除了一段:

scrollHeight 值沒有變化。MDN 上說了:

沒有垂直滾動條的情況下,scrollHeight值與元素視圖填充所有內容所需要的最小值clientHeight相同

scrollHeight 確實會隨著用戶輸入內容多少而增減,但是僅限于出現滾動條的情況,對于題設這個情況必然不適用,因為需求就是不能出現滾動條(嚴格來說是超出可視區域)。你可以在獲取 scrollHeight 的值之前先把文本框高度設為 0 強制讓滾動條出現,但是這樣可能使頁面發生閃爍,而且性能也低。

split('\n')

DOM 屬性靠不住,那我自己算文本高度不行嗎?說我拿出所有文本,按換行符拆分,看有多少行,行數 * 行高 不就是最終文本高度嗎?

額。。。當文本沒有折行的情況下是這樣。。。

contenteditable

contenteditable 確實是一個(相對)可行的方案,但是作為一個踩過坑的先行者勸解你:不到萬不得已,contenteditable 不要碰。這個玩意各個瀏覽器實現都不一樣,各種奇葩行為,光一個換行符就足夠折磨你半天。

當然這里還沒有到那么復雜的地步,但是你得先會把“復制——粘貼”過去的樣式去掉才行

筆者的方法

說了那么多廢話,那么究竟該怎么辦呢?這里筆者提供一種方法。

當然首先聲明:筆者的方法未必是最簡單的,如有其它更簡單的方案歡迎留言提出。

我們想一下,textarea 不能按照內容自適應高度,div 可以啊,能不能先把文本填到一個 div 里,div 的高度就應該是文本框所需高度(當 padding、line-height 等樣式都一致的情況下),這時獲取 div 的高度賦值給文本框高度不就行了嗎。

就是這樣的思路。我們也不需要專門使用 JS 獲取,只要讓 div 把父元素撐起來,絕對定位 textarea 元素讓文本框占滿整個父元素大小就好了。

直接上代碼:

<style>#parent {width: 500px;font: 12px monospace;position: relative;}#dummy {padding: 2px;border: 1px solid;visibility: hidden;}#dummy::after {content: "\A";}#textarea {position: absolute;left: 0;right: 0;top: 0;bottom: 0;resize: none;width: 100%;font: inherit;} </style> <div id="parent"><div id="dummy"></div><textarea id="textarea"oninput="document.getElementById('dummy').textContent = this.value"></textarea> </div>

這里查看運行結果:https://codepen.io/CarterLi/p...

三個要點:

  • 字體相關樣式 #dummy 和 textarea 兩元素必須完全一致,差一點就可能出現兩者高度對不上的情況。
  • #dummy 中 white-space: pre-wrap 醒目。否則會出現 HTML 中吞空格、換行符的情況。
  • 就算有了 white-space: pre-wrap,HTML 仍然會吞掉最后的換行符。解決方案是在 #dummy 最后插入一個換行符元素。可以是 <br />,也可以是一個偽元素。偽元素中換行符的寫法是 \A(即換行符的 ASCII 碼 10 的十六進制表示。不能寫 \n)
  • 代碼中是用 JS 給 #dummy 賦值。項目中如果你用 vuejs 或 angular 等 MVVM 框架,直接把文本框的值綁定到 div 上就好,非常方便。

    如果你要限制文本框的最大最小高度,在 #dummy 上直接設置 min-height max-height 即可。

    最后說一句:把 textarea 蓋到一個 div 上的做法還可以簡單的實現文本框的語法高亮,讀者可以想想怎么做。

    總結

    以上是生活随笔為你收集整理的编写自适应高度的 textarea的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。