Auto-resize Textarea ทำให้ความสูงของ Textarea ปรับตัวตามเนื้อหาอัตโนมัติ ทำให้ผู้ใช้เห็นข้อความทั้งหมดโดยไม่ต้องเลื่อน Scroll ภายใน Textarea
หลักการทำงาน
- ฟัง Event
input(เกิดทุกครั้งที่เนื้อหาเปลี่ยน) - ตั้งค่า
height = "auto"เพื่อคำนวณขนาดจริง - ตั้งค่า
height = scrollHeight + "px"ให้เท่ากับความสูงของเนื้อหา
ตัวอย่าง: Auto-resize Textarea
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Auto-resize Textarea</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
.resizeArea {
width: 100%;
min-height: 50px;
max-height: 300px;
padding: 10px;
font-family: inherit;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
overflow-y: hidden; /* ซ่อน scrollbar ระหว่าง resize */
resize: none; /* ป้องกันการ resize ด้วยมือ */
}
</style>
</head>
<body>
<h1>Textarea ขยายอัตโนมัติ (Auto-resize)</h1>
<p>พิมพ์หรือวางข้อความยาวๆ ลงไปดู</p>
<textarea class="resizeArea" placeholder="พิมพ์ข้อความที่นี่... จะขยายอัตโนมัติ"></textarea>
<script>
let resizeEle = document.querySelector(".resizeArea");
resizeEle.addEventListener("input", resizeTextArea, false);
function resizeTextArea() {
// รีเซ็ตความสูงเพื่อคำนวณใหม่
this.style.height = "auto";
// ตั้งค่าเท่ากับ scrollHeight (ความสูงของเนื้อหาทั้งหมด)
this.style.height = this.scrollHeight + "px";
}
// เรียกครั้งแรกสำหรับค่าเริ่มต้น (ถ้ามีค่า pre-filled)
resizeTextArea.call(resizeEle);
</script>
</body>
</html>
ผลลัพธ์
Textarea เริ่มต้นสูง 1 บรรทัด → พิมพ์Enterหลายบรรทัด → ความสูงเพิ่มขึ้นอัตโนมัติ → วางข้อความยาว → ขยายจนถึง max-height (300px) แล้วค่อยมี Scrollbar
ปรับปรุง: รองรับ Padding และ Border (Box-sizing)
function resizeTextArea() {
this.style.height = "auto";
// คำนวณ padding + border เพื่อความแม่นยำ
const style = window.getComputedStyle(this);
const paddingTop = parseFloat(style.paddingTop);
const paddingBottom = parseFloat(style.paddingBottom);
const borderTop = parseFloat(style.borderTopWidth);
const borderBottom = parseFloat(style.borderBottomWidth);
const extraHeight = paddingTop + paddingBottom + borderTop + borderBottom;
this.style.height = (this.scrollHeight + extraHeight) + "px";
}
เวอร์ชัน Modern: ใช้ CSS field-sizing (Experimental)
/* CSS Only - ไม่ต้อง JavaScript! */
textarea {
field-sizing: content; /* Chrome 123+, Edge 123+ */
/* fallback */
min-height: 50px;
}
⚠️ ยังเป็น Experimental ตรวจสอบ Can I Use ก่อนใช้งานจริง
กรณีพิเศษ: จำกัดความสูงสูงสุด
function resizeTextArea() {
this.style.height = "auto";
const newHeight = Math.min(this.scrollHeight, 300); // จำกัด 300px
this.style.height = newHeight + "px";
// แสดง Scrollbar เมื่อเกิน max-height
this.style.overflowY = this.scrollHeight > 300 ? "auto" : "hidden";
}
ประสิทธิภาพ (Performance)
- Event
inputยิงบ่อยมาก → ใช้requestAnimationFrameหรือ Debounce หากมีปัญหา - หลีกเลี่ยง Layout Thrashing: อ่าน
scrollHeightแล้วเขียนheightทันที (อยู่ใน Event Handler เดียวกัน OK)