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

JavaScript ตรวจจับ Mobile Browser (User Agent Detection)


การตรวจจับอุปกรณ์มือถือด้วย User Agent

วิธีดั้งเดิมใช้ navigator.userAgent และ Regex เพื่อตรวจสอบว่าเป็นมือถือหรือไม่ แต่ ไม่แนะนำให้ใช้ใน Production เนื่องจาก User Agent สามารถปลอมแปลงได้ และรูปแบบเปลี่ยนแปลงตลอดเวลา

ตัวอย่างโค้ด (วิธีเก่า - สำหรับการศึกษา)

<!DOCTYPE html>
<html lang="th">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Mobile Detection</title>
  <style>
    body { font-family: 'Segoe UI', sans-serif; padding: 20px; max-width: 600px; margin: 0 auto; text-align: center; }
    .result { font-size: 24px; font-weight: bold; margin: 30px 0; padding: 20px; border-radius: 8px; }
    .mobile { background: #e8f5e9; color: #2e7d32; }
    .desktop { background: #e3f2fd; color: #1565c0; }
    .ua-box { background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 4px; font-family: monospace; font-size: 12px; text-align: left; overflow-x: auto; white-space: pre-wrap; max-height: 200px; }
    button { padding: 12px 24px; background: #7e32d4; color: white; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; }
  </style>
</head>
<body>
  <h1>ตรวจจับ Mobile Browser (User Agent)</h1>
  <button id="detectBtn">ตรวจสอบอุปกรณ์</button>
  <div class="result" id="result">กดปุ่มเพื่อตรวจสอบ</div>
  <h3>User Agent String:</h3>
  <div class="ua-box" id="uaBox"></div>

  <script>
    const btn = document.getElementById('detectBtn');
    const result = document.getElementById('result');
    const uaBox = document.getElementById('uaBox');
    
    uaBox.textContent = navigator.userAgent;
    
    btn.addEventListener('click', () => {
      // วิธีเก่า: User Agent Sniffing
      const ua = navigator.userAgent;
      const isMobile = /iPhone|iPad|iPod|Android/i.test(ua);
      
      if (isMobile) {
        result.textContent = '📱 นี่คืออุปกรณ์มือถือ (Mobile)';
        result.className = 'result mobile';
      } else {
        result.textContent = '🖥️ นี่คือเดสก์ท็อป (Desktop)';
        result.className = 'result desktop';
      }
    });
  </script>
</body>
</html>

❌ ทำไม User Agent Sniffing ไม่แนะนำ?

  • User Agent Spoofing: ผู้ใช้/เครื่องมือสามารถเปลี่ยน UA string ได้ง่าย
  • mantenimiento ยาก: UA strings เปลี่ยนแปลงตลอดเวลา (Browser updates, อุปกรณ์ใหม่)
  • False Positives/Negatives: แท็บเล็ตอาจถูกจับว่า Desktop หรือ Mobile ผิด
  • Chrome/Firefox ลดข้อมูลใน UA: User Agent Reduction / User-Agent Client Hints

✅ วิธีที่แนะนำ: Feature Detection & Responsive Design

1. CSS Media Queries (Best for Layout)

/* CSS - ไม่ต้องใช้ JS */
@media (max-width: 768px) { .mobile-only { display: block; } }
@media (min-width: 769px) { .desktop-only { display: block; } }
@media (hover: none) and (pointer: coarse) { /* Touch device */ }
@media (hover: hover) and (pointer: fine) { /* Mouse device */ }

2. JavaScript: window.matchMedia()

// ตรวจสอบขนาดจอแบบ Reactive
const mobileQuery = window.matchMedia('(max-width: 768px)');
const touchQuery = window.matchMedia('(hover: none) and (pointer: coarse)');

function handleMobileChange(e) {
  if (e.matches) {
    console.log('Mobile view');
    document.body.classList.add('mobile-view');
  } else {
    console.log('Desktop view');
    document.body.classList.remove('mobile-view');
  }
}

mobileQuery.addEventListener('change', handleMobileChange);
// Initial check
handleMobileChange(mobileQuery);

3. Touch Detection

const isTouchDevice = () => {
  return ('ontouchstart' in window) || 
         navigator.maxTouchPoints > 0 ||
         window.matchMedia('(pointer: coarse)').matches;
};

4. Screen Size / Viewport

const isMobileViewport = () => window.innerWidth <= 768;
const isSmallScreen = () => screen.width <= 768; // Hardware screen

5. User-Agent Client Hints (Modern Standard)

// ต้องขอ permission ก่อน (Secure context + Permissions Policy)
navigator.userAgentData?.getHighEntropyValues(['platform', 'mobile', 'model'])
  .then(uaData => {
    console.log('Mobile:', uaData.mobile); // true/false
    console.log('Platform:', uaData.platform); // "Android", "iOS", "Windows", etc.
    console.log('Model:', uaData.model); // "Pixel 7", "iPhone 15", etc.
  });

สรุป: เลือกวิธีไหนดี?

สถานการณ์วิธีที่แนะนำ
ปรับ Layout/UICSS Media Queries
โหลด Resource แบบ ConditionalJS matchMedia / Dynamic Import
Touch-specific Featurespointer: coarse / Touch Events
Analytics / LoggingUser-Agent Client Hints (ถ้ารองรับ) + Fallback
Legacy Support (IE11)UA Sniffing (เป็นทางเลือกสุดท้าย)

ตัวอย่าง Modern Detection Utility

const DeviceDetector = {
  isMobile() {
    return window.matchMedia('(max-width: 768px)').matches;
  },
  isTouch() {
    return window.matchMedia('(pointer: coarse)').matches;
  },
  isLandscape() {
    return window.matchMedia('(orientation: landscape)').matches;
  },
  async getDeviceInfo() {
    if (navigator.userAgentData) {
      try {
        const hints = await navigator.userAgentData.getHighEntropyValues(['platform', 'mobile', 'model']);
        return {
          platform: hints.platform,
          mobile: hints.mobile,
          model: hints.model
        };
      } catch (e) { /* fallback */ }
    }
    return { platform: navigator.platform, mobile: this.isMobile() };
  }
};