小智 231
由于我没有找到可以复制/粘贴的无jQuery答案,这里是我使用的解决方案:
function clickEvent(e) {
// e = Mouse click event.
var rect = e.target.getBoundingClientRect();
var x = e.clientX - rect.left; //x position within the element.
var y = e.clientY - rect.top; //y position within the element.
}
Run Code Online (Sandbox Code Playgroud)
Spi*_*der 156
对于使用JQuery的人:
有时,当您有嵌套元素时,其中一个元素附加了事件,理解您的浏览器看作父母的内容可能会令人困惑.在这里,您可以指定哪个父级.
您获取鼠标位置,然后从父元素的偏移位置中减去它.
var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;
Run Code Online (Sandbox Code Playgroud)
如果您尝试在滚动窗格内的页面上获取鼠标位置:
var x = (evt.pageX - $('#element').offset().left) + self.frame.scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + self.frame.scrollTop();
Run Code Online (Sandbox Code Playgroud)
或者相对于页面的位置:
var x = (evt.pageX - $('#element').offset().left) + $(window).scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Run Code Online (Sandbox Code Playgroud)
请注意以下性能优化:
var offset = $('#element').offset();
// Then refer to
var x = evt.pageX - offset.left;
Run Code Online (Sandbox Code Playgroud)
通过这种方式,JQuery不必查找#element
每一行.
小智 56
以下计算与canvas元素的鼠标位置关系:
var example = document.getElementById('example');
example.onmousemove = function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,this
引用example
元素,并且e
是onmousemove
事件.
Atr*_*sis 31
我在2010年发现了这个问题,但似乎没有人满意它:纯粹的javascript中没有答案,当引用元素嵌套在其他可以绝对定位的内容时返回相对坐标.这是我的解决方案:
function getRelativeCoordinates (event, referenceElement) {
const position = {
x: event.pageX,
y: event.pageY
};
const offset = {
left: referenceElement.offsetLeft,
top: referenceElement.offsetTop
};
let reference = referenceElement.offsetParent;
while(reference){
offset.left += reference.offsetLeft;
offset.top += reference.offsetTop;
reference = reference.offsetParent;
}
return {
x: position.x - offset.left,
y: position.y - offset.top,
};
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ith 19
可以在这里找到关于这个问题难度的好文章:http://www.quirksmode.org/js/events_properties.html#position
使用那里描述的技术,您可以在文档中找到鼠标位置.然后你只需检查它是否在元素的边界框内,你可以通过调用element.getBoundingClientRect()找到它,它将返回一个具有以下属性的对象:{bottom,height,left,right,top,width }.从那里可以轻松地弄清楚你的元素内部是否发生过.
Fab*_*rts 11
我尝试了所有这些解决方案,并且由于使用矩阵转换的容器(panzoom库)进行了特殊设置而无法使用。即使缩放和平移,这也会返回正确的值:
mouseevent(e) {
const x = e.offsetX
const y = e.offsetY
}
Run Code Online (Sandbox Code Playgroud)
但前提是没有孩子。可以通过使用CSS使这些孩子对事件“不可见”来规避此问题:
#container.element-dragging *:not(.dragging) {
pointer-events: none;
}
Run Code Online (Sandbox Code Playgroud)
在dragstart / dragstop函数中,.element-dragging
在容器和.dragging
元素本身上切换类。
我+1''Mark van Wyk的答案,因为它让我朝着正确的方向前进,但并没有为我解决它.我在另一个元素中包含的元素中仍然有一个偏移.
FOllowing为我解决了它:
x = e.pageX - this.offsetLeft - $(elem).offset().left;
y = e.pageY - this.offsetTop - $(elem).offset().top;
Run Code Online (Sandbox Code Playgroud)
换句话说 - 我只是叠加了嵌套的所有元素的所有偏移量
我遇到了这个问题,但为了让我的情况下工作(使用的dragover一个DOM元素上(不是画布在我的情况)),我发现,你只需要使用offsetX
和offsetY
对的dragover鼠标事件.
onDragOver(event){
var x = event.offsetX;
var y = event.offsetY;
}
Run Code Online (Sandbox Code Playgroud)
上述答案都不是令人满意的IMO,所以这就是我使用的:
// Cross-browser AddEventListener
function ael(e, n, h){
if( e.addEventListener ){
e.addEventListener(n, h, true);
}else{
e.attachEvent('on'+n, h);
}
}
var touch = 'ontouchstart' in document.documentElement; // true if touch device
var mx, my; // always has current mouse position IN WINDOW
if(touch){
ael(document, 'touchmove', function(e){var ori=e;mx=ori.changedTouches[0].pageX;my=ori.changedTouches[0].pageY} );
}else{
ael(document, 'mousemove', function(e){mx=e.clientX;my=e.clientY} );
}
// local mouse X,Y position in element
function showLocalPos(e){
document.title = (mx - e.getBoundingClientRect().left)
+ 'x'
+ Math.round(my - e.getBoundingClientRect().top);
}
Run Code Online (Sandbox Code Playgroud)
如果您需要知道当前页面的Y滚动位置:
var yscroll = window.pageYOffset
|| (document.documentElement && document.documentElement.scrollTop)
|| document.body.scrollTop; // scroll Y position in page
Run Code Online (Sandbox Code Playgroud)
摘自本教程,由于顶级评论进行了更正:
function getMousePos( canvas, evt ) {
var rect = canvas.getBoundingClientRect();
return {
x: Math.floor( ( evt.clientX - rect.left ) / ( rect.right - rect.left ) * canvas.width ),
y: Math.floor( ( evt.clientY - rect.top ) / ( rect.bottom - rect.top ) * canvas.height )
};
}
Run Code Online (Sandbox Code Playgroud)
在画布上使用如下:
var canvas = document.getElementById( 'myCanvas' );
canvas.addEventListener( 'mousemove', function( evt ) {
var mousePos = getMousePos( canvas, evt );
} );
Run Code Online (Sandbox Code Playgroud)
canvas.onmousedown = function(e) {
pos_left = e.pageX - e.currentTarget.offsetLeft;
pos_top = e.pageY - e.currentTarget.offsetTop;
console.log(pos_left, pos_top)
}
Run Code Online (Sandbox Code Playgroud)
HTMLElement.offsetLeft
的HTMLElement.offsetLeft
只读属性返回当前元素的左上角偏移到内左侧的像素的数量HTMLElement.offsetParent
的节点。
对于块级元素,offsetTop
、offsetLeft
、offsetWidth
和offsetHeight
描述元素相对于 的边框框offsetParent
。
然而,对于行内的元素(如span
),其可以包从一行到下一,offsetTop
并且offsetLeft
描述第一边界框中的位置(使用Element.getClientRects()
以获得其宽度和高度),而offsetWidth
和offsetHeight
描述的边界的边界框的尺寸(用于Element.getBoundingClientRect()
获取其位置)。因此,左边、顶部、宽度和高度为offsetLeft
、offsetTop
、offsetWidth
和 的offsetHeight
框将不是带有换行文本的跨度的边界框。
HTMLElement.offsetTop
的HTMLElement.offsetTop
只读属性返回电流元件相对于所述的顶部的距离offsetParent
的节点。
鼠标事件.pageX
的pageX
只读属性返回事件相对于整个文档的像素的坐标的X(水平)。此属性考虑了页面的任何水平滚动。
鼠标事件.pageY
的MouseEvent.pageY
只读属性返回Y(垂直)在事件相对于整个文档的像素的坐标。此属性考虑了页面的任何垂直滚动。
更多解释请参见 Mozilla 开发者网络:
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageX https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageY https://开头developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop
对于那些为移动设备和/或带有触摸屏的笔记本电脑/显示器开发常规网站或 PWA(渐进式 Web 应用程序)的人,那么您来到这里是因为您可能已经习惯了鼠标事件,并且对触摸有时会带来痛苦的体验不熟悉事件……耶!
只有3条规则:
mousemove
或touchmove
事件。mousedown
或touchstart
事件。不用说,事件更复杂,touch
因为事件可能不止一个,而且它们比鼠标事件更灵活(复杂)。我只打算在这里介绍一下。是的,我很懒,但这是最常见的触摸类型,所以就这样。
var posTop;
var posLeft;
function handleMouseDown(evt) {
var e = evt || window.event; // Because Firefox, etc.
posTop = e.target.offsetTop;
posLeft = e.target.offsetLeft;
e.target.style.background = "red";
// The statement above would be better handled by CSS
// but it's just an example of a generic visible indicator.
}
function handleMouseMove(evt) {
var e = evt || window.event;
var x = e.offsetX; // Wonderfully
var y = e.offsetY; // Simple!
e.target.innerHTML = "Mouse: " + x + ", " + y;
if (posTop)
e.target.innerHTML += "<br>" + (x + posLeft) + ", " + (y + posTop);
}
function handleMouseOut(evt) {
var e = evt || window.event;
e.target.innerHTML = "";
}
function handleMouseUp(evt) {
var e = evt || window.event;
e.target.style.background = "yellow";
}
function handleTouchStart(evt) {
var e = evt || window.event;
var rect = e.target.getBoundingClientRect();
posTop = rect.top;
posLeft = rect.left;
e.target.style.background = "green";
e.preventDefault(); // Unnecessary if using Vue.js
e.stopPropagation(); // Same deal here
}
function handleTouchMove(evt) {
var e = evt || window.event;
var pageX = e.touches[0].clientX; // Touches are page-relative
var pageY = e.touches[0].clientY; // not target-relative
var x = pageX - posLeft;
var y = pageY - posTop;
e.target.innerHTML = "Touch: " + x + ", " + y;
e.target.innerHTML += "<br>" + pageX + ", " + pageY;
e.preventDefault();
e.stopPropagation();
}
function handleTouchEnd(evt) {
var e = evt || window.event;
e.target.style.background = "yellow";
// Yes, I'm being lazy and doing the same as mouseout here
// but obviously you could do something different if needed.
e.preventDefault();
e.stopPropagation();
}
Run Code Online (Sandbox Code Playgroud)
div {
background: yellow;
height: 100px;
left: 50px;
position: absolute;
top: 80px;
user-select: none; /* Disable text selection */
-ms-user-select: none;
width: 100px;
}
Run Code Online (Sandbox Code Playgroud)
<div
onmousedown="handleMouseDown()"
onmousemove="handleMouseMove()"
onmouseout="handleMouseOut()"
onmouseup="handleMouseUp()"
ontouchstart="handleTouchStart()"
ontouchmove="handleTouchMove()"
ontouchend="handleTouchEnd()">
</div>
Move over box for coordinates relative to top left of box.<br>
Hold mouse down or touch to change color.<br>
Drag to turn on coordinates relative to top left of page.
Run Code Online (Sandbox Code Playgroud)
更喜欢使用Vue.js?我愿意!那么您的 HTML 将如下所示:
<div @mousedown="handleMouseDown"
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
@touchstart.stop.prevent="handleTouchStart"
@touchmove.stop.prevent="handleTouchMove"
@touchend.stop.prevent="handleTouchEnd">
Run Code Online (Sandbox Code Playgroud)
小智 5
如果您想获取与一个元素相关的 layerX 和 layerY,也许您可以尝试?
let bbox_rect = document.getElementById("dom-ID").getBoundingClientRect()
let layerX = e.clientX-bbox_rect.left
let layerY = e.clientY-bbox_rect.top
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
232640 次 |
最近记录: |