Signatur
Beschreibung
Die schreibgeschützte Eigenschaft clientX gibt an, an welcher horizontalen Position im Viewport (dem sichtbaren Bereich des Browserfensters) ein Mausereignis ausgelöst wurde. Der Wert wird in CSS-Pixeln vom linken Rand des Viewports aus gemessen. Klickt man ganz links in den sichtbaren Bereich, ist clientX also 0, auch wenn die Seite horizontal gescrollt ist.
Damit unterscheidet sich clientX von verwandten Koordinaten: pageX bezieht sich auf das gesamte Dokument und rechnet den Scroll-Versatz mit ein, screenX auf den physischen Bildschirm, und offsetX auf den Innenabstandsrand (Padding-Kante) des Zielelements. clientX ist die natürliche Wahl, wenn man mit Element.getBoundingClientRect() arbeitet, weil beide dasselbe Koordinatensystem verwenden.
Typische Einsatzgebiete sind Drag-and-Drop, benutzerdefinierte Tooltips und Kontextmenüs mit position: fixed, Zeichenflächen auf <canvas> sowie Schieberegler. Da PointerEvent und WheelEvent von MouseEvent erben, steht clientX auch dort zur Verfügung. Bei Touch-Ereignissen liegt der Wert dagegen am einzelnen Touch-Objekt (z. B. event.touches[0].clientX).
Rückgabewert
double, der Nachkommastellen haben kann (z. B. bei Zoom oder hochauflösenden Displays). Bei synthetischen Ereignissen ohne Angabe ist der Wert 0.Beispiele
Klickposition im Viewport ausgeben
document.addEventListener('click', (event) => {
console.log(`clientX: ${event.clientX}, pageX: ${event.pageX}`);
});
Klickposition relativ zu einem Canvas bestimmen
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.addEventListener('pointerdown', (event) => {
const rect = canvas.getBoundingClientRect();
// clientX und rect.left nutzen dasselbe Koordinatensystem
const scaleX = canvas.width / rect.width;
const x = (event.clientX - rect.left) * scaleX;
const y = (event.clientY - rect.top) * (canvas.height / rect.height);
ctx.fillRect(x - 2, y - 2, 4, 4);
console.log(`Punkt bei x=${Math.round(x)}, y=${Math.round(y)}`);
});
Tooltip mit position: fixed dem Mauszeiger folgen lassen
const tooltip = document.createElement('div');
tooltip.textContent = 'Hinweis';
Object.assign(tooltip.style, { position: 'fixed', pointerEvents: 'none' });
document.body.append(tooltip);
const onMove = (event) => {
// fixed-Positionierung bezieht sich ebenfalls auf den Viewport
tooltip.style.left = `${event.clientX + 12}px`;
tooltip.style.top = `${event.clientY + 12}px`;
};
document.addEventListener('mousemove', onMove);
// Später wieder entfernen:
// document.removeEventListener('mousemove', onMove);
Horizontaler Schieberegler per Drag
const track = document.querySelector('.track');
const thumb = document.querySelector('.thumb');
const update = (clientX) => {
const rect = track.getBoundingClientRect();
const ratio = Math.min(Math.max((clientX - rect.left) / rect.width, 0), 1);
thumb.style.left = `${ratio * 100}%`;
console.log(`Wert: ${Math.round(ratio * 100)}`);
};
track.addEventListener('pointerdown', (event) => {
track.setPointerCapture(event.pointerId);
update(event.clientX);
});
track.addEventListener('pointermove', (event) => {
if (track.hasPointerCapture(event.pointerId)) update(event.clientX);
});
// Wichtig · Fallstricke
- Nicht mit
pageXverwechseln:clientXignoriert den Scroll-Versatz. Für Dokumentkoordinaten giltevent.clientX + window.scrollX(entsprichtpageX). - Kombination mit
getBoundingClientRect(): Für Positionen relativ zu einem Element immerevent.clientX - rect.leftrechnen.offsetXist in manchen Fällen (Rahmen, Transformationen, verschachtelte Kindelemente alstarget) unzuverlässig. - Nachkommastellen: Moderne Browser liefern teils gebrochene Werte. Für Pixel-Vergleiche ggf.
Math.round()verwenden. - CSS-Transformationen und Zoom: Bei skalierten Elementen (
transform: scale()) oder Canvas-Größen, die von der CSS-Größe abweichen, muss man den Wert selbst umrechnen. - iframes: Der Wert bezieht sich auf den Viewport des Dokuments, in dem das Ereignis ausgelöst wird, nicht auf das oberste Fenster.
- Touch:
TouchEventhat kein eigenesclientX. Stattdessenevent.touches[0].clientXverwenden oder besser gleich Pointer Events nutzen. - Synthetische Ereignisse: Bei
new MouseEvent('click', { clientX: 50 })lässt sich der Wert setzen. Ohne Angabe ist er0. Auch bei per Tastatur ausgelöstenclick-Ereignissen ist er oft0. - Der Alias
MouseEvent.xliefert denselben Wert.