摘要:但是現(xiàn)在產(chǎn)品經(jīng)理說了需要這個文本框可以根據(jù)用戶輸入內(nèi)容自適應(yīng)其高度。想法很簡單,當(dāng)用戶輸入的文本超過了文本框自身高度時不是會出現(xiàn)滾動條嘛,那么自然而然就能想到這個屬性。就應(yīng)該是用戶輸入文本的真實高度,至少超過文本框既定高度時是這樣。
文本框是很常見的輸入控件,我相信只要寫過表單的肯定接觸過 textarea 這個元素。
OK。但是現(xiàn)在產(chǎn)品經(jīng)理說了:需要這個文本框可以根據(jù)用戶輸入內(nèi)容自適應(yīng)其高度。
height: auto有些初學(xué)者可能會想:自適應(yīng)高度不就是 height: auto 么?可是你想一下,一個 textarea 沒有手工給它指定過樣式,不應(yīng)該就默認是 height: auto 么?但是它還是有自己的初始高度,并沒有像一個 div 那樣高度為 0。
與 div 不同,textarea 的默認高度不是根據(jù)其內(nèi)容自適應(yīng),而是由屬性 rows 指定,其默認值是 2。rows 這個屬性(Attribute)只接受正整數(shù),指定其他值瀏覽器會忽略掉其值,比如你寫 rows="auto" 那么 rows 就是 2,rows="0" 也是 2。
所以指定 height: auto 是行不通的,height 屬性必須人工指定其值。
scrollHeight遇到過這個問題的同學(xué)(比如當(dāng)初的筆者),肯定想到過 scrollHeight 這個 DOM 屬性。想法很簡單,當(dāng)用戶輸入的文本超過了文本框自身高度時不是會出現(xiàn)滾動條嘛,那么自然而然就能想到 scrollHeight 這個屬性。scrollHeight 就應(yīng)該是用戶輸入文本的真實高度,至少超過文本框既定高度時是這樣。
那么問題來了:如果沒超過呢?
OK 我知道你會先指定 rows="1" 讓文本框默認高度只有一行。但是考慮這種情況:用戶先輸入了很多行文本
然后刪除了一段:
scrollHeight 值沒有變化。MDN 上說了:
沒有垂直滾動條的情況下,scrollHeight值與元素視圖填充所有內(nèi)容所需要的最小值clientHeight相同
scrollHeight 確實會隨著用戶輸入內(nèi)容多少而增減,但是僅限于出現(xiàn)滾動條的情況,對于題設(shè)這個情況必然不適用,因為需求就是不能出現(xiàn)滾動條(嚴格來說是超出可視區(qū)域)。你可以在獲取 scrollHeight 的值之前先把文本框高度設(shè)為 0 強制讓滾動條出現(xiàn),但是這樣可能使頁面發(fā)生閃爍,而且性能也低。
split(" ")DOM 屬性靠不住,那我自己算文本高度不行嗎?說我拿出所有文本,按換行符拆分,看有多少行,行數(shù) * 行高 不就是最終文本高度嗎?
額。。。當(dāng)文本沒有折行的情況下是這樣。。。
contenteditablecontenteditable 確實是一個(相對)可行的方案,但是作為一個踩過坑的先行者勸解你:不到萬不得已,contenteditable 不要碰。這個玩意各個瀏覽器實現(xiàn)都不一樣,各種奇葩行為,光一個換行符就足夠折磨你半天。
當(dāng)然這里還沒有到那么復(fù)雜的地步,但是你得先會把“復(fù)制——粘貼”過去的樣式去掉才行
筆者的方法說了那么多廢話,那么究竟該怎么辦呢?這里筆者提供一種方法。
當(dāng)然首先聲明:筆者的方法未必是最簡單的,如有其它更簡單的方案歡迎留言提出。
我們想一下,textarea 不能按照內(nèi)容自適應(yīng)高度,div 可以啊,能不能先把文本填到一個 div 里,div 的高度就應(yīng)該是文本框所需高度(當(dāng) padding、line-height 等樣式都一致的情況下),這時獲取 div 的高度賦值給文本框高度不就行了嗎。
就是這樣的思路。我們也不需要專門使用 JS 獲取,只要讓 div 把父元素撐起來,絕對定位 textarea 元素讓文本框占滿整個父元素大小就好了。
直接上代碼:
這里查看運行結(jié)果:https://codepen.io/CarterLi/p...
三個要點:
字體相關(guān)樣式 #dummy 和 textarea 兩元素必須完全一致,差一點就可能出現(xiàn)兩者高度對不上的情況。
#dummy 中 white-space: pre-wrap 醒目。否則會出現(xiàn) HTML 中吞空格、換行符的情況。
就算有了 white-space: pre-wrap,HTML 仍然會吞掉最后的換行符。解決方案是在 #dummy 最后插入一個換行符元素??梢允?
,也可以是一個偽元素。偽元素中換行符的寫法是 A(即換行符的 ASCII 碼 10 的十六進制表示。不能寫
)
代碼中是用 JS 給 #dummy 賦值。項目中如果你用 vuejs 或 angular 等 MVVM 框架,直接把文本框的值綁定到 div 上就好,非常方便。
如果你要限制文本框的最大最小高度,在 #dummy 上直接設(shè)置 min-height max-height 即可。
完最后說一句:把 textarea 蓋到一個 div 上的做法還可以簡單的實現(xiàn)文本框的語法高亮,讀者可以想想怎么做。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/53721.html
摘要:但是現(xiàn)在產(chǎn)品經(jīng)理說了需要這個文本框可以根據(jù)用戶輸入內(nèi)容自適應(yīng)其高度。想法很簡單,當(dāng)用戶輸入的文本超過了文本框自身高度時不是會出現(xiàn)滾動條嘛,那么自然而然就能想到這個屬性。就應(yīng)該是用戶輸入文本的真實高度,至少超過文本框既定高度時是這樣。 文本框是很常見的輸入控件,我相信只要寫過表單的肯定接觸過 textarea 這個元素。 OK。但是現(xiàn)在產(chǎn)品經(jīng)理說了:需要這個文本框可以根據(jù)用戶輸入內(nèi)容自適...
摘要:今天的任務(wù)是生成一個高度自適應(yīng)的而且也可以設(shè)置最小高度和最大高度。但是有一個問題當(dāng)想從大變到小的時候,這個不能反映文字的實際高度,所以這個方法不是很適合。高度跟著文字的多少走的,而且不需要動畫。用的方式生成一個無用的用來計算的高度。 今天的任務(wù)是生成一個高度自適應(yīng)的textarea,而且也可以設(shè)置最小高度和最大高度。最簡單的方法textarea的屬性是overflow:auto;那么如...
摘要:使用該組件注意一個問題就是不要在可視化區(qū)域的節(jié)點上使用樣式,否則會出現(xiàn)當(dāng)鼠標焦點小時光標和小水滴無法消失的情況地址項目地址參考鏈接模擬文本域輕松實現(xiàn)高度自適應(yīng)如何讓元素只能輸入純文本 使用contenteditable+div模擬textarea文本域?qū)崿F(xiàn)高度自適應(yīng) 開發(fā)過程中由于需要在發(fā)送消息的時候需要有一個可以高度自適應(yīng)的文本域,一開始是使用textarea并搭配auto-size...
摘要:使用該組件注意一個問題就是不要在可視化區(qū)域的節(jié)點上使用樣式,否則會出現(xiàn)當(dāng)鼠標焦點小時光標和小水滴無法消失的情況地址項目地址參考鏈接模擬文本域輕松實現(xiàn)高度自適應(yīng)如何讓元素只能輸入純文本 使用contenteditable+div模擬textarea文本域?qū)崿F(xiàn)高度自適應(yīng) 開發(fā)過程中由于需要在發(fā)送消息的時候需要有一個可以高度自適應(yīng)的文本域,一開始是使用textarea并搭配auto-size...
閱讀 2003·2021-11-23 10:08
閱讀 2336·2021-11-22 15:25
閱讀 3275·2021-11-11 16:55
閱讀 771·2021-11-04 16:05
閱讀 2603·2021-09-10 10:51
閱讀 712·2019-08-29 15:38
閱讀 1583·2019-08-29 14:11
閱讀 3487·2019-08-29 12:42