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

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

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

ความแตกต่าง clientY vs pageY vs screenY

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

ตัวอย่าง: แสดงพิกัด 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;
element.addEventListener('mousedown', (e) => {
  isDragging = true;
  offsetX = e.clientX - element.getBoundingClientRect().left;
  offsetY = e.clientY - element.getBoundingClientRect().top;
});

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

ข้อควรระวัง

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

สรุป

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