Как получить координаты мышевика для элемента, имеющего преобразование CSS3?

Я хочу определить , где произошел 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 Модуль .

Эксперимент без преобразования CSS (работает)

запутано? Попробуйте следующий кусок 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 (не удается)

Теперь, Попробуйте добавить 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.

В этом примере единственное преобразование было масштабированием, поэтому я мог бы увеличить коэффициент масштабирования для расчета правильной координаты. Однако, если мы думаем о произвольных преобразованиях (масштаб, вращении, перевод, перевод, матрицу) и даже вложенные преобразования (преобразованный элемент внутри другого преобразованного элемента), то нам действительно нужен лучший способ расчета координат.

47
задан Denilson Sá Maia 21 July 2011 в 20:09
поделиться