Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

สร้าง Textarea ขยายอัตโนมัติ (Auto-resize Textarea) ด้วย JavaScript

Auto-resize Textarea ทำให้ความสูงของ Textarea ปรับตัวตามเนื้อหาอัตโนมัติ ทำให้ผู้ใช้เห็นข้อความทั้งหมดโดยไม่ต้องเลื่อน Scroll ภายใน Textarea

หลักการทำงาน

  1. ฟัง Event input (เกิดทุกครั้งที่เนื้อหาเปลี่ยน)
  2. ตั้งค่า height = "auto" เพื่อคำนวณขนาดจริง
  3. ตั้งค่า 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)