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

บทบาทของ clientX Mouse Event ใน JavaScript

clientX เป็น Property ของ MouseEvent ที่คืนค่า พิกัดแนวนอน (X-coordinate) ของเมาส์ **สัมพันธ์กับ Viewport (บริเวณมองเห็นของเบราว์เซอร์)** ไม่รวม Scroll Offset

ความแตกต่าง clientX vs pageX vs screenX

Propertyจุดอ้างอิง (Origin)รวม Scroll?ใช้เมื่อไหร่
clientXViewport (Browser Window Visible Area)❌ ไม่รวมPositioning Tooltip, Modal, Context Menu ภายใน Viewport
pageXDocument (ทั้งหน้า รวม Scroll)✅ รวมPositioning Element ตำแหน่งจริงในเอกสาร, Drag & Drop
screenXScreen (Monitor Physical)❌ ไม่รวมMulti-monitor, Fullscreen Positioning, OS-level UI
offsetXTarget Element (Padding Edge)❌Position ภายใน Element เป้าหมาย
layerXCurrent Layer (Non-standard)❌หลีกเลี่ยง ใช้ offsetX แทน

ตัวอย่าง: แสดงพิกัด clientX, clientY เมื่อคลิก

<!DOCTYPE html>
<html>
<body>
  <p onclick="coordsFunc(event)" style="height: 200px; background: #f0f0f0; border: 1px solid #ccc;">
    คลิกที่นี่เพื่อดูพิกัด clientX / clientY (สัมพันธ์ Viewport)
  </p>
  <div id="output"></div>

  <script>
    function coordsFunc(event) {
      const x = event.clientX;
      const y = event.clientY;
      document.getElementById('output').innerHTML =
        `clientX: ${x}, clientY: ${y} <br>
         pageX: ${event.pageX}, pageY: ${event.pageY} <br>
         screenX: ${event.screenX}, screenY: ${event.screenY} <br>
         offsetX: ${event.offsetX}, offsetY: ${event.offsetY}`;
    }
  </script>
</body>
</html>

การใช้งานจริง (Use Cases)

1. Tooltip / Popover Positioning

element.addEventListener('mousemove', (e) => {
  tooltip.style.left = e.clientX + 10 + 'px';
  tooltip.style.top = e.clientY + 10 + 'px';
  tooltip.style.display = 'block';
});

2. Context Menu (Right-click Menu)

document.addEventListener('contextmenu', (e) => {
  e.preventDefault();
  contextMenu.style.left = e.clientX + 'px';
  contextMenu.style.top = e.clientY + 'px';
  contextMenu.classList.add('show');
});

3. Drag & Drop (ควรใช้ clientX/Y สำหรับการเคลื่อนที่ใน Viewport)

let isDragging = false;
let offsetX, offsetY;

element.addEventListener('mousedown', (e) => {
  isDragging = true;
  const rect = element.getBoundingClientRect();
  offsetX = e.clientX - rect.left;
  offsetY = e.clientY - rect.top;
});

document.addEventListener('mousemove', (e) => {
  if (!isDragging) return;
  element.style.left = (e.clientX - offsetX) + 'px';
  element.style.top = (e.clientY - offsetY) + 'px';
});

document.addEventListener('mouseup', () => isDragging = false);

ข้อควรระวัง

  • clientX เป็น Integer (Pixel) แต่อาจเป็น Float ใน High-DPI/Zoom
  • ไม่รวม Scroll → หากหน้า Scroll แล้ว clientX ของจุดเดียวกันบนหน้าจอจะเท่าเดิม แต่ pageX จะเปลี่ยน
  • ใน Touch Event ใช้ touch.clientX (จาก event.touches[0].clientX)
  • Pointer Events (pointerdown, pointermove) ก็มี clientX เช่นกัน (แนะนำใช้ Pointer Events แทน Mouse/Touch แยก)

สรุป

clientX = พิกัด X สัมพันธ์ Viewport (ไม่รวม Scroll) ใช้สำหรับ UI Positioning (Tooltip, Modal, Context Menu, Drag in Viewport) | pageX = สัมพันธ์ Document (รวม Scroll) | screenX = สัมพันธ์จอภาพ