У нас есть компонент, который выглядит примерно так:
class ClickableField {
onClick = e => {
const bounds = e.currentTarget.getBoundingClientRect();
const dx = e.clientX - bounds.left;
// Do some stuff with dx that assumes it is between 0 and bounds.right,
// i.e. the click was actually within the element supposedly clicked on.
}
render() {
const { props: { top, left, height, width, children }, onClick } = this;
return <svg
style={{
position: 'absolute', overflow: 'hidden',
top, left, height, width,
}}
onClick={onClick}
>
{children}
</svg>;
}
}
Очень редко мы получаем отрицательное значение dx
, что означает e.clientX < e.currentTarget.getBoundingClientRect().left
. Как e.clientX
может быть меньше e.currentTarget.getBoundingClientRect().left
? Это означает, что событие мыши произошло слева от левой границы элемента, то есть за пределами элемента полностью, и поэтому не должно было запускать этот обработчик с самого начала.
Как может предположить props: { top, left, height, width }
, это элемент, который мы перемещаем и изменяем размер, вы можете представить, что элемент переместился с момента заполнения события мыши clientX
, но обработчики событий происходят синхронно, верно, поэтому я не понимаю, как это могло произойти. Мы не выполняем этот расчет ни в каком обратном вызове и не делаем ничего асинхронного. Я знаю, что React создает событие syntheti c здесь за кулисами, но он все еще делает это синхронно, верно?
Другая возможность, как мне кажется, заключается в том, что щелчок происходит по дочернему элементу, который пузырился здесь, и этот дочерний элемент не находится в границах родительского, но это также невозможно, поскольку переполнение элемента SVG установлено на hidden
(и, здесь не показано, но children
здесь действительно вписывается в ограничивающая область, определенная здесь реквизитами { top, left, height, width }
).
Итак, что осталось? Как может такая ситуация? (Игнорировать события, которые вызывают негатив здесь, достаточно просто, но я хочу знать, как это было спровоцировано в первую очередь.)