Now.js Framework Documentation

Now.js Framework Documentation

TabsComponent - คอมโพเนนต์แท็บสำหรับ Now.js

TH 22 Nov 2025 09:03

TabsComponent - คอมโพเนนต์แท็บสำหรับ Now.js

เอกสารฉบับนี้อธิบาย TabsComponent ซึ่งเป็นคอมโพเนนต์สำหรับสร้างแท็บ (Tabs) ที่มีความสามารถครบถ้วน รองรับการเข้าถึง (Accessibility) และการนำทางด้วยคีย์บอร์ด

📋 สารบัญ

  1. ภาพรวม
  2. การติดตั้งและนำเข้า
  3. การใช้งานพื้นฐาน
  4. คุณสมบัติ HTML
  5. ตัวเลือกการกำหนดค่า
  6. การนำทางด้วยคีย์บอร์ด
  7. การเข้าถึง (Accessibility)
  8. อีเวนต์
  9. JavaScript API
  10. ตัวอย่างการใช้งาน
  11. API Reference
  12. แนวทางปฏิบัติที่ดี
  13. ข้อควรระวัง

ภาพรวม

TabsComponent เป็นคอมโพเนนต์สำหรับสร้างแท็บที่มีคุณภาพระดับ Production พร้อมการรองรับ ARIA และการนำทางด้วยคีย์บอร์ดอย่างสมบูรณ์

ฟีเจอร์หลัก

  • เริ่มทำงานอัตโนมัติ: กำหนดค่าผ่าน data-component="tabs" ได้ทันที
  • รองรับ ARIA เต็มรูปแบบ: มี attributes ที่จำเป็นสำหรับ screen readers
  • การนำทางด้วยคีย์บอร์ด: รองรับ Arrow keys, Home, End
  • กำหนดค่าผ่าน Data Attributes: ตั้งค่าทั้งหมดผ่าน HTML ได้
  • Event Callbacks: ฟังก์ชัน callback สำหรับ lifecycle events
  • แอนิเมชัน: รองรับ transition animations
  • จัดการแท็บแบบไดนามิก: เพิ่ม/ลบแท็บได้แบบ real-time
  • รองรับทั้งแนวนอนและแนวตั้ง: เลือกทิศทางการแสดงผลได้

เมื่อไหร่ควรใช้ TabsComponent

ใช้ TabsComponent เมื่อ:

  • ต้องการแบ่งเนื้อหาออกเป็นหมวดหมู่ที่สลับกันได้
  • ต้องการประหยัดพื้นที่หน้าจอโดยซ่อนเนื้อหาบางส่วน
  • ต้องการให้ผู้ใช้เลือกดูข้อมูลในมุมมองต่างๆ
  • ต้องการ UI ที่รองรับการเข้าถึงอย่างเต็มรูปแบบ
  • ต้องการแท็บที่ทำงานได้ทั้งบนเดสก์ท็อปและมือถือ

ไม่ควรใช้ TabsComponent เมื่อ:

  • มีเนื้อหาเพียงเล็กน้อยที่แสดงได้ทั้งหมดในหน้าเดียว
  • ต้องการให้ผู้ใช้เห็นเนื้อหาทั้งหมดพร้อมกัน (ใช้ accordion แทน)
  • มีขั้นตอนที่ต้องทำตามลำดับ (ใช้ stepper/wizard แทน)

การติดตั้งและนำเข้า

TabsComponent โหลดมาพร้อมกับ Now.js Framework และพร้อมใช้งานทันทีผ่าน window object:

// ไม่ต้อง import - พร้อมใช้งานทันที
console.log(window.TabsComponent); // อ็อบเจ็กต์ TabsComponent

สิ่งที่ต้องพึ่งพา

  • Now.js Core – Framework หลัก
  • CSS (tabs.css) – สไตล์สำหรับแท็บ (นำเข้าผ่าน main.css)

การใช้งานพื้นฐาน

1. การใช้งานผ่าน HTML (แนะนำ)

<div data-component="tabs">
  <div class="tab-buttons" role="tablist">
    <button class="tab-button" data-tab="overview" role="tab">ภาพรวม</button>
    <button class="tab-button" data-tab="features" role="tab">ฟีเจอร์</button>
    <button class="tab-button" data-tab="usage" role="tab">การใช้งาน</button>
  </div>
  <div class="tab-content">
    <div class="tab-pane" data-tab="overview" role="tabpanel">
      <h3>ภาพรวม</h3>
      <p>เนื้อหาภาพรวม...</p>
    </div>
    <div class="tab-pane" data-tab="features" role="tabpanel">
      <h3>ฟีเจอร์</h3>
      <p>รายการฟีเจอร์...</p>
    </div>
    <div class="tab-pane" data-tab="usage" role="tabpanel">
      <h3>การใช้งาน</h3>
      <p>วิธีการใช้งาน...</p>
    </div>
  </div>
</div>

2. การใช้งานผ่าน JavaScript

const element = document.querySelector('#my-tabs');

const instance = TabsComponent.create(element, {
  defaultTab: 'features',
  keyboard: true,
  animation: true,
  onTabChange: (tabId, previousTab) => {
    console.log(`เปลี่ยนจาก ${previousTab} ไป ${tabId}`);
  }
});

3. การเริ่มทำงานอัตโนมัติ

TabsComponent จะสร้าง instance อัตโนมัติสำหรับ elements ที่มี data-component="tabs":

<!-- จะถูกสร้างอัตโนมัติเมื่อหน้าโหลด -->
<div data-component="tabs">
  <!-- เนื้อหาแท็บ -->
</div>

คุณสมบัติ HTML

TabsComponent รองรับ data attributes เหล่านี้สำหรับการกำหนดค่า:

คุณสมบัติพื้นฐาน

Attribute ประเภท ค่าเริ่มต้น คำอธิบาย
data-default-tab string null ID ของแท็บที่จะเปิดเป็นค่าเริ่มต้น
data-keyboard boolean true เปิด/ปิดการนำทางด้วยคีย์บอร์ด
data-animation boolean true เปิด/ปิดแอนิเมชันการเปลี่ยนแท็บ
data-animation-duration number 300 ระยะเวลาแอนิเมชัน (มิลลิวินาที)
data-orientation string 'horizontal' ทิศทางการแสดงผล (horizontal หรือ vertical)
data-aria-label string 'Tabs' ARIA label สำหรับ tablist
data-lazy boolean false โหลดเนื้อหาแท็บแบบ lazy loading
data-debug boolean false เปิดโหมด debug (แสดง console logs)

ตัวอย่างการใช้ Attributes

<div data-component="tabs"
     data-default-tab="settings"
     data-keyboard="true"
     data-animation="true"
     data-orientation="horizontal">
  <!-- เนื้อหาแท็บ -->
</div>

ตัวเลือกการกำหนดค่า

เมื่อสร้าง instance ด้วย JavaScript สามารถกำหนดค่าได้ทั้งหมด:

const instance = TabsComponent.create(element, {
  // การตั้งค่าพื้นฐาน
  defaultTab: null,           // แท็บเริ่มต้น (null = แท็บแรก)
  keyboard: true,             // เปิดการนำทางด้วยคีย์บอร์ด
  animation: true,            // เปิดแอนิเมชัน
  animationDuration: 300,     // ระยะเวลาแอนิเมชัน (ms)

  // พฤติกรรม
  destroyOnHidden: false,     // ทำลาย instance เมื่อ element ถูกลบ
  lazy: false,                // โหลดเนื้อหาแบบ lazy

  // การเข้าถึง
  ariaLabel: 'Tabs',          // ARIA label สำหรับ tablist
  orientation: 'horizontal',  // 'horizontal' หรือ 'vertical'

  // Event callbacks
  onInit: (instance) => {
    console.log('Tabs initialized');
  },
  beforeTabChange: (newTabId, oldTabId) => {
    // return false เพื่อยกเลิกการเปลี่ยนแท็บ
    return true;
  },
  onTabChange: (newTabId, oldTabId) => {
    console.log(`Changed from ${oldTabId} to ${newTabId}`);
  },
  onDestroy: (instance) => {
    console.log('Tabs destroyed');
  },

  // Debug
  debug: false                // เปิด console logging
});

การนำทางด้วยคีย์บอร์ด

TabsComponent รองรับการนำทางด้วยคีย์บอร์ดตามมาตรฐาน ARIA:

คีย์ที่รองรับ

คีย์ การทำงาน
(Arrow Right) ไปแท็บถัดไป (วนกลับไปแท็บแรกเมื่อถึงแท็บสุดท้าย)
(Arrow Left) ไปแท็บก่อนหน้า (วนไปแท็บสุดท้ายเมื่ออยู่แท็บแรก)
(Arrow Down) ไปแท็บถัดไป (สำหรับแนวตั้ง)
(Arrow Up) ไปแท็บก่อนหน้า (สำหรับแนวตั้ง)
Home ไปแท็บแรก
End ไปแท็บสุดท้าย
Tab ย้าย focus ไปยัง tab panel

ตัวอย่างการใช้งาน

<!-- คลิกที่แท็บแล้วใช้ Arrow keys เพื่อนำทาง -->
<div data-component="tabs" data-keyboard="true">
  <div class="tab-buttons" role="tablist">
    <button class="tab-button" data-tab="tab1">Tab 1</button>
    <button class="tab-button" data-tab="tab2">Tab 2</button>
    <button class="tab-button" data-tab="tab3">Tab 3</button>
  </div>
  <!-- panels -->
</div>

ปิดการนำทางด้วยคีย์บอร์ด

<div data-component="tabs" data-keyboard="false">
  <!-- แท็บที่ไม่รองรับคีย์บอร์ด -->
</div>

การเข้าถึง (Accessibility)

TabsComponent ปฏิบัติตามมาตรฐาน ARIA อย่างเต็มรูปแบบ

ARIA Attributes ที่ใช้

บน Tablist Container

  • role="tablist" - ระบุว่าเป็นรายการแท็บ
  • aria-orientation="horizontal|vertical" - ทิศทางของแท็บ
  • aria-label="..." - ป้ายกำกับสำหรับ screen readers

บน Tab Buttons

  • role="tab" - ระบุว่าเป็นปุ่มแท็บ
  • aria-selected="true|false" - สถานะการเลือก
  • aria-controls="panel-id" - เชื่อมโยงกับ panel
  • tabindex="0|-1" - จัดการ focus
  • id="tab-id" - ID ที่ไม่ซ้ำ

บน Tab Panels

  • role="tabpanel" - ระบุว่าเป็นพื้นที่เนื้อหาแท็บ
  • aria-labelledby="tab-id" - เชื่อมโยงกับปุ่มแท็บ
  • tabindex="0" - ทำให้ focus ได้
  • hidden - ซ่อน/แสดง panel
  • id="panel-id" - ID ที่ไม่ซ้ำ

ตัวอย่าง HTML ที่สมบูรณ์

<div data-component="tabs">
  <!-- Tablist -->
  <div class="tab-buttons" role="tablist" aria-orientation="horizontal" aria-label="Product Information">
    <button class="tab-button active"
            data-tab="description"
            role="tab"
            aria-selected="true"
            aria-controls="panel-description"
            tabindex="0"
            id="tab-description">
      คำอธิบาย
    </button>
    <button class="tab-button"
            data-tab="specs"
            role="tab"
            aria-selected="false"
            aria-controls="panel-specs"
            tabindex="-1"
            id="tab-specs">
      สเปค
    </button>
  </div>

  <!-- Tab Panels -->
  <div class="tab-content">
    <div class="tab-pane active"
         data-tab="description"
         role="tabpanel"
         aria-labelledby="tab-description"
         tabindex="0"
         id="panel-description">
      เนื้อหาคำอธิบาย...
    </div>
    <div class="tab-pane"
         data-tab="specs"
         role="tabpanel"
         aria-labelledby="tab-specs"
         tabindex="0"
         id="panel-specs"
         hidden>
      เนื้อหาสเปค...
    </div>
  </div>
</div>

อีเวนต์

TabsComponent ส่งอีเวนต์เมื่อมีการเปลี่ยนแปลง

ประเภทของอีเวนต์

อีเวนต์ เมื่อไหร่ รายละเอียด
tabs:tabchange เมื่อเปลี่ยนแท็บสำเร็จ {instance, tabId, previousTab, button, panel}

การฟังอีเวนต์

const element = document.querySelector('[data-component="tabs"]');

element.addEventListener('tabs:tabchange', (e) => {
  console.log('Tab changed to:', e.detail.tabId);
  console.log('Previous tab:', e.detail.previousTab);
  console.log('Tab button:', e.detail.button);
  console.log('Tab panel:', e.detail.panel);
  console.log('Instance:', e.detail.instance);
});

Event Callbacks

const instance = TabsComponent.create(element, {
  // เรียกเมื่อ component ถูกสร้าง
  onInit: function() {
    console.log('Tabs initialized', this);
  },

  // เรียกก่อนเปลี่ยนแท็บ (สามารถยกเลิกได้)
  beforeTabChange: function(newTabId, oldTabId) {
    if (newTabId === 'restricted') {
      alert('ไม่สามารถเข้าถึงแท็บนี้ได้');
      return false; // ยกเลิกการเปลี่ยนแท็บ
    }
    return true; // อนุญาตให้เปลี่ยนแท็บ
  },

  // เรียกหลังเปลี่ยนแท็บสำเร็จ
  onTabChange: function(newTabId, oldTabId) {
    console.log(`Changed from ${oldTabId} to ${newTabId}`);

    // บันทึกแท็บปัจจุบันลง localStorage
    localStorage.setItem('lastTab', newTabId);
  },

  // เรียกเมื่อ component ถูกทำลาย
  onDestroy: function() {
    console.log('Tabs destroyed');
  }
});

JavaScript API

TabsComponent มี methods สำหรับควบคุมผ่าน JavaScript

สร้าง Instance

const instance = TabsComponent.create(element, options);

Parameters:

  • element (HTMLElement) - Element ที่จะสร้างแท็บ
  • options (Object) - ตัวเลือกการกำหนดค่า

Returns: Instance object

อ่าน Instance

// จาก element โดยตรง
const instance = TabsComponent.getInstance(element);

// จาก instance property
const instance = element.tabsInstance;

เปลี่ยนแท็บ

// ผ่าน instance method
instance.switchTab('tab-id');

// หรือผ่าน static method
TabsComponent.switchTab(instance, 'tab-id');

Parameters:

  • tabId (string) - ID ของแท็บที่ต้องการเปลี่ยนไป

Returns: boolean - true ถ้าเปลี่ยนสำเร็จ, false ถ้าไม่สำเร็จ

อ่านแท็บปัจจุบัน

const activeTab = instance.getActiveTab();
console.log('Current tab:', activeTab); // 'tab-id'

Returns: string - ID ของแท็บที่กำลังแสดงอยู่

รีเฟรช Instance

// สแกนหาปุ่มและ panels ใหม่
instance.refresh();

ใช้เมื่อมีการเพิ่ม/ลบแท็บแบบไดนามิก

ทำลาย Instance

// ทำลาย instance และเคลียร์ทรัพยากร
instance.destroy();

ลบ event listeners และ ARIA attributes ทั้งหมด

ตัวอย่างการใช้งาน

1. แท็บพื้นฐาน

<div data-component="tabs">
  <div class="tab-buttons">
    <button class="tab-button" data-tab="home">หน้าแรก</button>
    <button class="tab-button" data-tab="about">เกี่ยวกับ</button>
    <button class="tab-button" data-tab="contact">ติดต่อ</button>
  </div>
  <div class="tab-content">
    <div class="tab-pane" data-tab="home">
      <h2>หน้าแรก</h2>
      <p>ยินดีต้อนรับ...</p>
    </div>
    <div class="tab-pane" data-tab="about">
      <h2>เกี่ยวกับเรา</h2>
      <p>เราคือ...</p>
    </div>
    <div class="tab-pane" data-tab="contact">
      <h2>ติดต่อเรา</h2>
      <p>โทร: 02-xxx-xxxx</p>
    </div>
  </div>
</div>

2. กำหนดแท็บเริ่มต้น

<div data-component="tabs" data-default-tab="profile">
  <div class="tab-buttons">
    <button class="tab-button" data-tab="dashboard">Dashboard</button>
    <button class="tab-button" data-tab="profile">โปรไฟล์</button>
    <button class="tab-button" data-tab="settings">ตั้งค่า</button>
  </div>
  <div class="tab-content">
    <!-- panels -->
  </div>
</div>

3. แท็บแนวตั้ง

<div data-component="tabs" data-orientation="vertical" style="display: flex;">
  <div class="tab-buttons" style="flex-direction: column; border-right: 1px solid #ddd;">
    <button class="tab-button" data-tab="general">ทั่วไป</button>
    <button class="tab-button" data-tab="security">ความปลอดภัย</button>
    <button class="tab-button" data-tab="privacy">ความเป็นส่วนตัว</button>
  </div>
  <div class="tab-content" style="flex: 1; padding-left: 20px;">
    <!-- panels -->
  </div>
</div>

4. ควบคุมด้วย JavaScript

<div id="my-tabs" data-component="tabs">
  <!-- tabs content -->
</div>

<button onclick="switchToTab('settings')">ไปที่ตั้งค่า</button>

<script>
function switchToTab(tabId) {
  const instance = TabsComponent.getInstance('#my-tabs');
  if (instance) {
    instance.switchTab(tabId);
  }
}
</script>

5. บันทึกแท็บปัจจุบันลง localStorage

const tabs = TabsComponent.create(element, {
  onInit: function() {
    // โหลดแท็บที่บันทึกไว้
    const savedTab = localStorage.getItem('currentTab');
    if (savedTab && this.tabIds.includes(savedTab)) {
      this.switchTab(savedTab);
    }
  },
  onTabChange: function(newTabId) {
    // บันทึกแท็บปัจจุบัน
    localStorage.setItem('currentTab', newTabId);
  }
});

6. ยืนยันก่อนเปลี่ยนแท็บ

const tabs = TabsComponent.create(element, {
  beforeTabChange: function(newTabId, oldTabId) {
    if (oldTabId === 'form' && formHasUnsavedChanges()) {
      return confirm('มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก ต้องการออกจากหน้านี้หรือไม่?');
    }
    return true;
  }
});

7. โหลดเนื้อหาแบบ Lazy Loading

const tabs = TabsComponent.create(element, {
  lazy: true,
  onTabChange: async function(tabId) {
    const panel = this.panels.find(p => p.dataset.tab === tabId);

    // ตรวจสอบว่าโหลดแล้วหรือยัง
    if (!panel.dataset.loaded) {
      panel.innerHTML = '<p>กำลังโหลด...</p>';

      // โหลดข้อมูลจาก API
      const response = await fetch(`/api/tabs/${tabId}`);
      const html = await response.text();

      panel.innerHTML = html;
      panel.dataset.loaded = 'true';
    }
  }
});

8. แท็บแบบไดนามิก

<div id="dynamic-tabs" data-component="tabs">
  <div class="tab-buttons"></div>
  <div class="tab-content"></div>
</div>

<button onclick="addTab()">เพิ่มแท็บ</button>

<script>
function addTab() {
  const instance = TabsComponent.getInstance('#dynamic-tabs');
  const newTabId = `tab-${Date.now()}`;

  // เพิ่มปุ่มแท็บ
  const button = document.createElement('button');
  button.className = 'tab-button';
  button.dataset.tab = newTabId;
  button.textContent = `Tab ${instance.tabIds.length + 1}`;
  instance.element.querySelector('.tab-buttons').appendChild(button);

  // เพิ่ม panel
  const panel = document.createElement('div');
  panel.className = 'tab-pane';
  panel.dataset.tab = newTabId;
  panel.textContent = `Content for ${newTabId}`;
  instance.element.querySelector('.tab-content').appendChild(panel);

  // รีเฟรช instance
  instance.refresh();

  // เปลี่ยนไปแท็บใหม่
  instance.switchTab(newTabId);
}
</script>

API Reference

TabsComponent.create(element, options)

สร้าง tabs instance ใหม่

Parameters:

  • element (HTMLElement) - Container element
  • options (Object) - Configuration options

Returns: Instance object

TabsComponent.getInstance(element)

อ่าน instance ที่มีอยู่

Parameters:

  • element (HTMLElement | string) - Element หรือ selector

Returns: Instance object หรือ null

TabsComponent.switchTab(instance, tabId, initial)

เปลี่ยนไปยังแท็บที่ระบุ

Parameters:

  • instance (Object) - Tabs instance
  • tabId (string) - ID ของแท็บ
  • initial (boolean) - เป็นการเปิดครั้งแรกหรือไม่

Returns: boolean

TabsComponent.refresh(instance)

สแกนหาปุ่มและ panels ใหม่

Parameters:

  • instance (Object) - Tabs instance

TabsComponent.destroy(instance)

ทำลาย instance

Parameters:

  • instance (Object) - Tabs instance

Instance Methods

instance.switchTab(tabId)

เปลี่ยนแท็บ

Parameters:

  • tabId (string) - ID ของแท็บ

Returns: boolean

instance.getActiveTab()

อ่าน ID ของแท็บปัจจุบัน

Returns: string

instance.refresh()

รีเฟรช instance

instance.destroy()

ทำลาย instance

แนวทางปฏิบัติที่ดี

✅ ควรทำ

  1. ใช้ ARIA attributes ที่ถูกต้อง

    <div class="tab-buttons" role="tablist">
     <button class="tab-button" data-tab="tab1" role="tab">Tab 1</button>
    </div>
  2. ใช้ ID ที่มีความหมาย

    <button data-tab="user-profile">โปรไฟล์</button>
    <button data-tab="user-settings">ตั้งค่า</button>
  3. จัดกลุ่มเนื้อหาที่เกี่ยวข้องกัน

    • แท็บควรมีเนื้อหาที่เกี่ยวข้องกัน
    • ไม่ควรมีแท็บมากเกินไป (แนะนำ 3-7 แท็บ)
  4. ใช้ keyboard navigation

    <div data-component="tabs" data-keyboard="true">
  5. บันทึกสถานะแท็บ

    onTabChange: (tabId) => {
     localStorage.setItem('activeTab', tabId);
    }

❌ ไม่ควรทำ

  1. อย่าซ้อนแท็บหลายชั้น

    <!-- ❌ ไม่ดี -->
    <div data-component="tabs">
     <div class="tab-pane">
       <div data-component="tabs">
         <!-- แท็บซ้อนแท็บ - สับสน -->
       </div>
     </div>
    </div>
  2. อย่าใช้แท็บสำหรับ navigation หลัก

    <!-- ❌ ไม่ดี - ใช้ menu แทน -->
    <div data-component="tabs">
     <button data-tab="home">หน้าแรก</button>
     <button data-tab="products">สินค้า</button>
     <button data-tab="contact">ติดต่อ</button>
    </div>
  3. อย่าลืม role attributes

    <!-- ❌ ไม่ดี - ขาด ARIA -->
    <div data-component="tabs">
     <div class="tab-buttons">
       <button data-tab="tab1">Tab 1</button>
     </div>
    </div>
    
    <!-- ✅ ดี -->
    <div data-component="tabs">
     <div class="tab-buttons" role="tablist">
       <button class="tab-button" data-tab="tab1" role="tab">Tab 1</button>
     </div>
    </div>

ข้อควรระวัง

⚠️ ข้อผิดพลาดที่พบบ่อย

  1. ลืมใส่ data-tab attribute

    <!-- ❌ ไม่ทำงาน -->
    <button class="tab-button">Tab 1</button>
    
    <!-- ✅ ถูกต้อง -->
    <button class="tab-button" data-tab="tab1">Tab 1</button>
  2. ID ของปุ่มและ panel ไม่ตรงกัน

    <!-- ❌ ไม่ทำงาน -->
    <button data-tab="profile">โปรไฟล์</button>
    <div data-tab="user-profile">...</div>
    
    <!-- ✅ ถูกต้อง -->
    <button data-tab="profile">โปรไฟล์</button>
    <div data-tab="profile">...</div>
  3. ไม่มี .tab-button หรือ .tab-pane class

    <!-- ❌ ไม่ทำงาน -->
    <button data-tab="tab1">Tab 1</button>
    <div data-tab="tab1">Content</div>
    
    <!-- ✅ ถูกต้อง -->
    <button class="tab-button" data-tab="tab1">Tab 1</button>
    <div class="tab-pane" data-tab="tab1">Content</div>

💡 เคล็ดลับ

  1. ใช้ CSS transitions สำหรับแอนิเมชันที่นุ่มนวล

    .tab-pane {
     opacity: 0;
     transition: opacity 0.3s ease;
    }
    
    .tab-pane.active {
     opacity: 1;
    }
  2. ใช้ beforeTabChange เพื่อ validate

    beforeTabChange: (newTab, oldTab) => {
     if (oldTab === 'form' && !isFormValid()) {
       alert('กรุณากรอกข้อมูลให้ครบถ้วน');
       return false;
     }
     return true;
    }
  3. ใช้ refresh() หลังเพิ่ม/ลบแท็บ

    // เพิ่มแท็บใหม่
    addNewTab();
    
    // รีเฟรช instance
    instance.refresh();

เพิ่มเติม