如何自動調整文本區域的大小以適應其內容
如何編寫一個函數來在文本區域的內容擴展超過其默認高度時自動調整其大小。
在本教程中,我們將使用 CheatCode 的全棧 JavaScript 框架 Joystick。 Joystick 將前端 UI 框架與用於構建應用的 Node.js 後端結合在一起。
首先,我們要通過 NPM 安裝 Joystick。確保在安裝之前使用 Node.js 16+ 以確保兼容性(如果您需要學習如何安裝 Node.js 或在計算機上運行多個版本,請先閱讀本教程):
終端
npm i -g @joystick.js/cli
這將在您的計算機上全局安裝操縱桿。安裝好之後,接下來我們新建一個項目:
終端
joystick create app
幾秒鐘後,您將看到一條消息已註銷到 cd
進入你的新項目並運行 joystick start
:
終端
cd app && joystick start
在此之後,您的應用應該可以運行了,我們可以開始了。
編寫自動調整大小函數
為了使我們的代碼盡可能靈活,首先,我們將編寫一個可重用的模塊來調整 textarea 元素的大小。 /lib
內部 運行 joystick create app
時為您創建的文件夾 ,添加一個新文件autoResize.js
:
/lib/autoResize.js
export default (DOMNode = {}, defaultHeight = 100) => {
// We'll handle the resize here...
};
首先,我們要從這個文件中導出一個帶有兩個參數的函數:
DOMNode
這是代表<textarea><textarea>
的 JavaScript DOM 節點 我們要控制高度的元素。defaultHeight
如果其內容的高度不強制增加高度,這是為 textarea 設置的最小高度。
/lib/autoResize.js
export default (DOMNode = {}, defaultHeight = 100) => {
if (DOMNode) {
// We'll handle the resize logic here...
}
};
接下來,我們想限制我們的邏輯只在 DOMNode
時運行 被傳遞給函數。這很重要,因為只要輸入的內容髮生變化,我們的函數就會被調用,也就是說,如果由於某種原因我們犯了一個錯誤並且沒有通過 DOMNode
(或者我們傳遞了錯誤的值),我們會在每次按鍵時觸發運行時錯誤——沒有 bueno。
/lib/autoResize.js
export default (DOMNode = {}, defaultHeight = 100) => {
if (DOMNode) {
const DOMNodeStyles = window.getComputedStyle(DOMNode);
const paddingTop = parseInt(DOMNodeStyles?.getPropertyValue('padding-top') || 0, 10);
const paddingBottom = parseInt(DOMNodeStyles?.getPropertyValue('padding-bottom') || 0, 10);
DOMNode.style.height = `${defaultHeight}px`;
DOMNode.style.height = `${DOMNode.scrollHeight - paddingTop - paddingBottom}px`;
}
};
上面,我們添加了整個自動調整大小的邏輯(這將使單步執行更容易)。
首先,因為我們正在處理高度,我們需要預測我們的輸入可能在其 CSS 中設置的任何填充。為了得到它,我們調用 window.getComputedStyle()
函數,傳入我們的 DOMNode
取回一個對象,其中包含應用於我們的 <textarea></textarea>
的所有樣式 .
與那些 DOMNodeStyles
,接下來,我們要獲取 textarea 的頂部和底部填充值,因為它們會在視覺上影響輸入的高度。為了得到它們,我們調用 .getPropertyValue()
DOMNodeStyles
上的方法 我們剛剛創建的對象,通過 padding-top
或 padding-bottom
.
請注意,我們將調用傳遞給 that 方法直接調用 parseInt()
.這是因為我們從這個方法返回的值是一個包含 px
的字符串 (即,如果我們的 padding-top
是 10px 我們會返回 "10px"
) 我們希望它像 10
這樣的普通整數 .
一旦我們將這些值存儲在 paddingTop
和 paddingBottom
,我們可以繼續調整文本區域的高度。
為此,我們需要直接修改style
textarea 的對象,設置它的 height
財產。我們想分兩步完成:首先,設置默認高度,然後設置相對於文本區域當前內容的高度。
我們想要這樣做是因為我們需要考慮用戶清除的輸入。如果這發生在輸入有足夠的內容來擴展高度之後,在清除時,輸入將保留設置的高度(因為滾動高度沒有改變)。
設置高度,我們直接設置height
DOMNode.style.height
的輸入屬性 , 首先設置它等於 defaultHeight
的串聯 變量和 px
像 ${defaultHeight}px
.接下來,我們重複相同的模式,這次將輸入設置為其當前的 scrollHeight
, 減去 paddingTop
和 paddingBottom
我們在上面得到了幾行的值,然後再次將結果整數與 px
連接起來 .
而已!現在,讓我們在 UI 中使用它,看看它是如何連接起來的。
使用自動調整大小功能
這是簡單的部分。為簡單起見,我們將修改在運行 joystick create app
時為我們創建的現有 UI 組件 早些時候。讓我們在 /ui/pages/index/index.js
處打開組件 並進行一些更改:
/ui/pages/index/index.js
import ui from '@joystick.js/ui';
const Index = ui.component({
css: `
label {
display: block;
font-size: 16px;
margin-bottom: 10px;
}
textarea {
display: block;
resize: none;
width: 300px;
height: 100px;
border: 1px solid #ddd;
padding: 10px;
}
`,
render: () => {
return `
<form>
<label>What's your life story?</label>
<textarea name="lifeStory"></textarea>
</form>
`;
},
});
export default Index;
將文件的現有內容替換為上述內容,開始我們要獲取 <textarea></textarea>
我們想自動調整在屏幕上渲染的高度。在render()
中 我們組件的函數,我們返回一個包含簡單 <form></form>
的 HTML 字符串 帶有 <label></label>
的元素 和一個 <textearea></textarea>
在裡面。
就在這之上,為了讓我們的 UI 看起來更漂亮,我們為 <label></label>
添加了一些 CSS 和 <textarea></textarea>
元素。注意:注意height
textarea 的屬性設置為 100px
.這很重要。這可以確保當我們的輸入第一次渲染時,它的視覺高度與 defaultHeight
匹配 我們正在傳遞給 autoResize()
.
/ui/pages/index/index.js
import ui from '@joystick.js/ui';
import autoResize from '../../../lib/autoResize';
const Index = ui.component({
events: {
'input textarea': (event) => {
autoResize(event.target, 100);
},
},
css: `...`,
render: () => {
return `
<form>
<label>What's your life story?</label>
<textarea name="lifeStory"></textarea>
</form>
`;
},
});
export default Index;
現在是重要的部分。上面,我們添加了一個 events
屬性給我們的組件。在此處傳遞的對像上,我們為 input
添加了一個事件監聽器 我們的 textarea
上的事件 元素。在檢測到事件時觸發的回調函數內部,使用 autoResize()
我們在上面導入的函數,我們傳入 event.target
— 或者,我們的 <textarea></textarea>
元素——後跟我們要設置的默認高度,以防文本區域被清除,100
.
這樣就可以了。現在如果我們打開瀏覽器到 http://localhost:2600
(確保您的應用程序正在運行),我們應該看到我們的 <textarea></textarea>
如果內容超過默認高度,則展開。
總結
在本教程中,我們學習瞭如何連接一個 autoresize 函數,該函數根據其內容動態調整 textarea 的高度。我們學習瞭如何使用 style
動態操作輸入的高度 屬性,確保考慮到填充的變化。最後,我們學習瞭如何使用我們的函數來響應 input
我們的 <textarea></textarea>
上的事件 .