How to get the MouseEvent coordinates for an element that has CSS3 Transform?
I want to detect where a MouseEvent has
occurred, in coordinates relative to the clicked element. Why? Because I want to add an absolutely positioned child element
at the clicked location.
I know how to detect it when no CSS3 transformations exist (see description below). However, when I add a CSS3 Transform, then my algorithm breaks, and I don't know how to fix it.
I'm not using any JavaScript library, and I want to understand how things work in plain JavaScript. So, please, don't answer with "just use jQuery".
By the way, I want a solution that works for all MouseEvents, not just "click". Not that it matters, because I believe all mouse events share the same properties, thus the same solution should work for all of them.
Background information
According to DOM
Level 2 specification, a MouseEvent has
few properties related to getting the event coordinates:
screenXandscreenYreturn
the screen coordinates (the origin is the top-left corner of user's monitor)clientXandclientYreturn
the coordinates relative the document viewport.
Thus, in order to find the position of the MouseEvent relative
to the clicked element content, I must do this math:
ev.clientX - this.getBoundingClientRect().left - this.clientLeft + this.scrollLeft
ev.clientXis
the coordinate relative to the document viewportthis.getBoundingClientRect().leftis
the position of the element relative to the document viewportthis.clientLeftis
the amount of border (and scrollbar) between the element boundary and the inner coordinatesthis.scrollLeftis
the amount of scrolling inside the element
getBoundingClientRect(), clientLeft and scrollLeft are
specified at CSSOM
View Module.
Experiment without CSS Transform (it works)
Confusing? Try the following piece
of JavaScript and HTML. Upon clicking, a red dot should appear exactly where the click has happened. This version is "quite simple" and works as expected.
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);
<div id="experiment" style="border: 5px inset #AAA; background: #CCC; height: 400px; position: relative; overflow: auto;">
<div style="width: 900px; height: 2px;"></div>
<div style="height: 900px; width: 2px;"></div>
</div>
Experiment adding a CSS Transform (it fails)
Now, try adding a CSS transform:
#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. */
}
The algorithm doesn't know about the transformations, and thus calculates a wrong position. What's more, the results are different between Firefox 3.6 and Chrome 12. Opera 11.50 behaves just like Chrome.
In this example, the only transformation was scaling, so I could multiply the scaling factor to calculate the correct coordinate. However, if we think about arbitrary transformations (scale, rotate, skew, translate, matrix), and even nested transformations
(a transformed element inside another transformed element), then we really need a better way to calculate the coordinates.
How to get the MouseEvent coordinates for an element that has CSS3 Transform?的更多相关文章
- Why AlloyFinger is so much smaller than hammerjs?
AlloyFinger is the mobile web gesture solution at present inside my company, major projects are in u ...
- OpenSceneGraph控制模型
OpenSceneGraph控制模型 转自:http://www.cppblog.com/eryar/archive/2012/05/28/176538.html 一.简介 对模型的控制就是修改模型的 ...
- 【RobotFramework】Selenium2Library类库关键字使用说明
Add CookieArguments:[ name | value | path=None | domain=None | secure=None | expiry=None ]Adds a coo ...
- pageX/Y, offset(), position(), scrollTop(), screenX/Y, clientX/Y, pageX/Y
event.pageX get mouse position Description: The mouse position relative to the left edge of the docu ...
- cocos2d中的可见性检测
游戏的在进行一次渲染的时候,通常会提交大量的渲染对象给gpu.在这些需要渲染的对象中,并不是所有对象都会出现镜头中,即有一部分对象是不可见的. 通常有两种方式来完成不可见对象的剔除工作: (1)直接交 ...
- js 导出Excel
最近从Silverlight这边转到javascript过来,现在要导出一个导出excel的功能.上级领导指示当页显示多少数据,就导出多少数据,没有必要从后台在去数据.以前也没有接触过这方面的,在网上 ...
- Easy Multiple Copy to Clipboard by ZeroClipboard
要实现在多个复制按钮复制的功能(具体代码在附件中,路径修改一下就行了): <%@ page language="java" import="java.util.*& ...
- 转:VS2008 vs2010中JQUERY智能提醒
第一步: 安装VS 2008 SP1 VS 2008 SP1 在Visual Studio中加了更丰富的JavaScript intellisense支持,对很大部分的JavaScript库加了代码完 ...
- appium点击屏幕(手势)
在android测试过程中,会遇到要点击一下屏幕的需求. 在appium旧版本使用下面代码点击android屏幕,没有报错.Map tap = new HashMap(); tap.put(" ...
随机推荐
- Docker推出了Docker云,给大家介绍下哈!
Docker推出了Docker云,给大家介绍下哈. 收到了Docker官网的邮件邀请,他们推出了Docker云:https://cloud.docker.com 账号信息栏目下有: 云提供商:眼下支持 ...
- hmm CDN检测
# -*- coding:utf-8 -*- import sys import re from hmmlearn import hmm import numpy as np from sklearn ...
- Regexp-Utils:基本
ylbtech-Regexp-Utils:基本 1.返回顶部 1. /** * 管理 */ var utils = { hostUrl: "http://localhost:8023&quo ...
- [jzoj 6092] [GDOI2019模拟2019.3.30] 附耳而至 解题报告 (平面图转对偶图+最小割)
题目链接: https://jzoj.net/senior/#main/show/6092 题目: 知识点--平面图转对偶图 在求最小割的时候,我们可以把平面图转为对偶图,用最短路来求最小割,这样会比 ...
- layer Tips参数使用
layer.tips(content, follow, options) - tips层type:4的深度定制.也是我本人比较喜欢的一个层类型,因为它拥有和msg一样的低调和自觉,而且会智能定位,即灵 ...
- HTML5音频可视化频谱跳动代码
今天学习到用canvas来写 HTML5音频可视化频谱跳动代码 将代码在此做一总结: <!DOCTYPE html> <html lang="en"> ...
- 安装Oracle 12c及解决遇到的问题
一.[INS-30131]执行安装程序验证所需的初始设置失败(原因:无法访问临时位置) 原文链接:https://blog.csdn.net/u013388049/article/details/85 ...
- Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)A. Protect Sheep
http://codeforces.com/contest/948/problem/A A. Protect Sheep Bob is a farmer. He has a large pastu ...
- [51nod1074]约瑟夫环V2
N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数.问最后剩下的人的编号. 例如:N = 3,K = 2.2号先出列,然后是1号,最后剩下的是3号. ...
- php的更新
因为 PHP 那“集百家之长”的蛋疼语法,加上社区氛围不好,很多人对新版本,新特征并无兴趣.本文将会介绍自 PHP5.2 起,直至 PHP5.6 中增加的新特征 本文目录:PHP5.2 以前:auto ...