Я хочу определить , где произошел A MouseEvent
, в координат относительно щелчкового элемента . Почему? Потому что я хочу добавить абсолютно позиционированный детский элемент в месте нажатия.
Я знаю, как обнаружить его, когда не существует преобразований CSS3 (см. Описание ниже). Однако, когда я добавляю преобразование CSS3, то мой алгоритм перерывается, и я не знаю, как это исправить.
Я не использую никакой библиотеки JavaScript, и я хочу понять, как все работает в простом JavaScript. Итак, пожалуйста, не отвечайте «Просто используйте jQuery».
Кстати, я хочу, чтобы решение, которое работает для всех мышевиков, а не просто «щелкнуть». Не то чтобы это важно, потому что я верю, что все события мыши делятся теми же свойствами, поэтому то же самое решение должно работать для всех них.
Согласно Спецификация DOM Уровень 2 , A MouseEvent
имеет несколько свойств, связанных с получением координат события:
ScreenX
и Screeny
Возвращение координат экрана (происхождение - верхний левый угол монитора пользователя) ClientX
и CLINGY
Вернуть координаты относительно просмотра документа. Таким образом, для того, чтобы найти позицию MouseEvent
относительно содержимого элемента клика, я должен сделать эту математику:
ev.clientX - this.getBoundingClientRect().left - this.clientLeft + this.scrollLeft
EV.clientx
- это координата относительно просмотра документов THE.getBoundingClientRect (). Слева
- это положение элемента относительно просмотра документов this.clientleft
- это количество границы (и прокрутки) между границей элемента и внутренние координаты Это.scrollleft
- это количество прокрутки внутри элемента GetBoundingClientRect ()
, ClientLeft
и Scrollleft
указывается в CSSOM View Модуль .
запутано? Попробуйте следующий кусок JavaScript и HTML . После нажатия красная точка должна появиться именно там, где произошло щелчок. Эта версия «довольно просто» и работает, как ожидалось.
function click_handler(ev) {
var rect = this.getBoundingClientRect();
var left = ev.clientX - rect.left - this.clientLeft + this.scrollLeft;
var top = ev.clientY - rect.top - this.clientTop + this.scrollTop;
var dot = document.createElement('div');
dot.setAttribute('style', 'position:absolute; width: 2px; height: 2px; top: '+top+'px; left: '+left+'px; background: red;');
this.appendChild(dot);
}
document.getElementById("experiment").addEventListener('click', click_handler, false);
Теперь, Попробуйте добавить CSS преобразования
:
#experiment {
transform: scale(0.5);
-moz-transform: scale(0.5);
-o-transform: scale(0.5);
-webkit-transform: scale(0.5);
/* Note that this is a very simple transformation. */
/* Remember to also think about more complex ones, as described below. */
}
Алгоритм не знает о преобразованиях, и, таким образом, вычисляет неправильный позиция. Более того, результаты различны между Firefox 3.6 и Chrome 12. Opera 11.50 ведет себя так же, как Chrome.
В этом примере единственное преобразование было масштабированием, поэтому я мог бы увеличить коэффициент масштабирования для расчета правильной координаты. Однако, если мы думаем о произвольных преобразованиях (масштаб, вращении, перевод, перевод, матрицу) и даже вложенные преобразования (преобразованный элемент внутри другого преобразованного элемента), то нам действительно нужен лучший способ расчета координат.