요소를 기준으로 마우스 위치 찾기
캔버스를 이용한 작은 그림 앱을 만들고 싶습니다.그래서 캔버스에서 마우스 위치를 찾아야 해요.
복사/붙여넣을 수 있는 jQuery 프리 답변을 찾을 수 없었기 때문에 사용한 솔루션은 다음과 같습니다.
document.getElementById('clickme').onclick = 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.
console.log("Left? : " + x + " ; Top? : " + y + ".");
}
#clickme {
margin-top: 20px;
margin-left: 100px;
border: 1px solid black;
cursor: pointer;
}
<div id="clickme">Click Me -<br>
(this box has margin-left: 100px; margin-top: 20px;)</div>
JQuery를 사용하는 사용자의 경우:
이벤트가 부가된 중첩된 요소가 있는 경우 브라우저의 상위 요소를 이해하기 어려울 수 있습니다.여기서 어떤 부모를 지정할 수 있습니다.
마우스 위치를 취한 다음 상위 요소의 간격띄우기 위치에서 뺍니다.
var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;
스크롤 창 안의 페이지에서 마우스 위치를 가져오려는 경우:
var x = (evt.pageX - $('#element').offset().left) + self.frame.scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + self.frame.scrollTop();
또는 페이지와 관련된 위치:
var x = (evt.pageX - $('#element').offset().left) + $(window).scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
다음의 퍼포먼스 최적화에 주의해 주세요.
var offset = $('#element').offset();
// Then refer to
var x = evt.pageX - offset.left;
하면 는 JQuery를 .#element
각 회선마다.
갱신하다
@anytimecoder의 응답에는 새로운 JavaScript 전용 버전이 있습니다.getBoundingClientRect()에 대한 브라우저 지원도 참조하십시오.
다음은 캔버스 요소에 대한 마우스 위치 관계를 계산합니다.
const example = document.getElementById('example');
example.onmousemove = function(e) {
const x = e.pageX - e.currentTarget.offsetLeft;
const y = e.pageY - e.currentTarget.offsetTop;
}
순수 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,
};
}
저는 이 모든 솔루션을 시도해 보았지만 매트릭스 변환 컨테이너(판줌 라이브러리)를 사용한 특별한 설정 때문에 효과가 없었습니다.이렇게 하면 확대/축소 및 상하좌우로 이동하더라도 올바른 값이 반환됩니다.
mouseevent(e) {
const x = e.offsetX,
y = e.offsetY
}
하지만 방해가 되는 요소가 없는 경우에만요.이는 CSS를 사용하여 이벤트에 대해 '보이지 않음'으로 함으로써 회피할 수 있습니다.
.child {
pointer-events: none;
}
이 문제의 문제의 상세한 것에 대하여는, http://www.quirksmode.org/js/events_properties.html#position 를 참조해 주세요.
여기에 설명된 기술을 사용하여 문서에서 마우스 위치를 찾을 수 있습니다. 자신이 안에 .element.getBoundingClientRect()
과 같은 가진 를 반환합니다.{ bottom, height, left, right, top, width }
여기서부터 요소 내부에서 발생했는지 여부를 파악하는 것은 매우 간단합니다.
이을 하게 만, ( DOM 오버를 사용하여)내에 적합하게 , 「DOM」을을 알았습니다.offsetX
★★★★★★★★★★★★★★★★★」offsetY
드래그오버 이벤트 때.
onDragOver(event){
var x = event.offsetX;
var y = event.offsetY;
}
1개의 요소에 관련된 레이어X 및 레이어Y를 취득하는 경우는, 다음과 같이 시험할 수 있습니다.
let bbox_rect = document.getElementById("dom-ID").getBoundingClientRect()
let layerX = e.clientX-bbox_rect.left
let layerY = e.clientY-bbox_rect.top
나는 마크 반 와이크의 대답이 나를 올바른 방향으로 이끌었기 때문에 +1'이라고 대답했지만, 나는 그것을 잘 해결하지 못했다.나는 다른 요소 안에 포함된 요소들에 대한 회화에 대한 오프셋이 여전히 있었다.
폴로잉으로 해결했습니다.
x = e.pageX - this.offsetLeft - $(elem).offset().left;
y = e.pageY - this.offsetTop - $(elem).offset().top;
즉, 중첩된 모든 요소의 모든 오프셋을 쌓기만 하면 됩니다.
모바일 디바이스용 일반 웹사이트 또는 터치스크린을 탑재한 노트북/모니터용 PWA(Progressive Web Apps)를 개발하시는 분들은 마우스 이벤트에 익숙하고 터치 이벤트의 고통스러운 경험을 처음 접하는 분입니다.야호!
규칙은 3가지뿐입니다.
- 때는 적게 .
mousemove
★★★★★★★★★★★★★★★★★」touchmove
벤트입입니니다 - 수 한 해 주세요.
mousedown
★★★★★★★★★★★★★★★★★」touchstart
벤트입입니니다 - 전파를 취소하고 터치 이벤트의 기본값을 방지하여 하이브리드 디바이스에서도 마우스 이벤트가 실행되지 않도록 합니다.
것도 없이, 은 더 복잡합니다만, 더 합니다.touch
이벤트에는 여러 개의 이벤트가 있을 수 있고 마우스 이벤트보다 유연성이 높기 때문입니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★에, 거기 ,, 게, 게, 게, 게, 게, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes, yes.
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();
}
div {
background: yellow;
height: 100px;
left: 50px;
position: absolute;
top: 80px;
user-select: none; /* Disable text selection */
-ms-user-select: none;
width: 100px;
}
<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.
Vue.js를 사용하시겠습니까?네! 그러면 HTML은 다음과 같습니다.
<div @mousedown="handleMouseDown"
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
@touchstart.stop.prevent="handleTouchStart"
@touchmove.stop.prevent="handleTouchMove"
@touchend.stop.prevent="handleTouchEnd">
위의 답변 중 어느 것도 만족스러운 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);
}
또한 페이지의 현재 Y 스크롤 위치를 알아야 하는 경우:
var yscroll = window.pageYOffset
|| (document.documentElement && document.documentElement.scrollTop)
|| document.body.scrollTop; // scroll Y position in page
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 )
};
}
캔버스에 다음과 같이 사용합니다.
var canvas = document.getElementById( 'myCanvas' );
canvas.addEventListener( 'mousemove', function( evt ) {
var mousePos = getMousePos( canvas, evt );
} );
canvas.onmousedown = function(e) {
pos_left = e.pageX - e.currentTarget.offsetLeft;
pos_top = e.pageY - e.currentTarget.offsetTop;
console.log(pos_left, pos_top)
}
HT Mlement. offset 왼쪽
HTMLElement.offsetLeft
은 현재 전용으로 합니다.HTMLElement.offsetParent
discloss.discloss.
요소에 대해서는, 「」를 참조해 주세요.offsetTop
,offsetLeft
,offsetWidth
, , , , 입니다.offsetHeight
describe describe describe describe describe describe 、 describe 、 describe 、 describe describe 。offsetParent
.
요소( 「」등)의 는, 다음과 같습니다.span
에서 다음을 할 수 것, > > > > > > > > > > > > > > > > > > > > > > > > > 。offsetTop
★★★★★★★★★★★★★★★★★」offsetLeft
첫 번째 테두리 상자의 위치를 설명합니다(사용).Element.getClientRects()
폭과 높이를 얻기 위해)를 선택합니다.offsetWidth
★★★★★★★★★★★★★★★★★」offsetHeight
테두리 상자의 치수를 설명합니다(용도).Element.getBoundingClientRect()
그 지위를 획득하기 위해서).왼쪽,, 가 라, 쪽, 비, 이, 이, 이, 이의 입니다.offsetLeft
,offsetTop
,offsetWidth
★★★★★★★★★★★★★★★★★」offsetHeight
는 줄바꿈된 텍스트가 있는 범위의 경계 상자가 되지 않습니다.
HTLelement.오프셋정상
HTMLElement.offsetTop
는 현재 할 때 " 전용"의 을 기준으로 합니다.offsetParent
discloss.discloss.
MouseEvent.pageX
pageX
읽기 전용 속성은 전체 문서를 기준으로 이벤트의 픽셀 단위로 X(수평) 좌표를 반환합니다.이 속성은 페이지의 수평 스크롤을 고려합니다.
MouseEvent. 페이지y
MouseEvent.pageY
읽기 전용 속성은 전체 문서를 기준으로 이벤트의 픽셀 단위로 Y(수직) 좌표를 반환합니다.이 속성은 페이지의 수직 스크롤을 고려합니다.
상세한 것에 대하여는, Mozilla Developer Network 를 참조해 주세요.
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
const findMousePositionRelativeToElement = (e) => {
const xClick = e.clientX - e.currentTarget.offsetLeft;
const yClick = e.clientY - e.currentTarget.offsetTop;
console.log(`x: ${xClick}`);
console.log(`y: ${yClick}`);
// or
const rect = e.currentTarget.getBoundingClientRect();
const xClick2 = e.clientX - rect.left;
const yClick2 = e.clientY - rect.top;
console.log(`x2: ${xClick2}`);
console.log(`y2: ${yClick2}`);
}
조금 늦은 건 알지만, PURE javascript와 연동됩니다.또한 요소가 뷰포트보다 크고 사용자가 스크롤한 경우 요소 내의 포인터의 좌표를 알 수 있습니다.
var element_offset_x ; // The distance from the left side of the element to the left of the content area
....// some code here (function declaration or element lookup )
element_offset_x = element.getBoundingClientRect().left - document.getElementsByTagName("html")[0].getBoundingClientRect().left ;
....// code here
function mouseMoveEvent(event)
{
var pointer_location = (event.clientX + window.pageXOffset) - element_offset_x ;
}
작동 방식.
먼저 현재 뷰포트에 대한 HTML 요소(콘텐츠 영역)의 위치를 확인합니다. 있는 반환되는 과 같습니다.getBoundingClientRect().left
그런 다음 이 숫자를 사용하여 요소와 컨텐츠 영역의 왼쪽 사이의 거리를 계산합니다.★★★★★★★★★★★★★★★★ element_offset_x = element.getBoundingClientRect().left......;
컨텐츠 영역으로부터 요소의 거리를 확인합니다. event.clientX
는 뷰포트에서 포인터의 거리를 나타냅니다.뷰포트와 내용 영역은 서로 다른 두 개의 엔티티이며 페이지가 스크롤되면 뷰포트가 이동할 수 있음을 이해하는 것이 중요합니다.따라서 clientX는 페이지가 스크롤되어도 같은 번호를 반환합니다.
이를 보완하려면 포인터의 x 위치(뷰포트를 기준으로 함)를 뷰포트의 x 위치(콘텐츠 영역을 기준으로 함)에 추가해야 합니다.의 X 다. window.pageXOffset.
@Spider의 솔루션을 기반으로 JQuery 이외의 버전은 다음과 같습니다.
// Get the container element's bounding box
var sides = document.getElementById("container").getBoundingClientRect();
// Apply the mouse event listener
document.getElementById("canvas").onmousemove = (e) => {
// Here 'self' is simply the current window's context
var x = (e.clientX - sides.left) + self.pageXOffset;
var y = (e.clientY - sides.top) + self.pageYOffset;
}
이 기능은 스크롤과 줌 모두에서 작동합니다(이 경우 플로트가 반환되는 경우도 있습니다).
하시면 됩니다.getBoudingClientRect()
relative
★★★★★★ 。
document.addEventListener("mousemove", (e) => {
let xCoord = e.clientX - e.target.getBoundingClientRect().left + e.offsetX
let yCoord = e.clientY - e.target.getBoundingClientRect().top + e.offsetY
console.log("xCoord", xCoord, "yCoord", yCoord)
})
당신은 그것을 얻을 수 있다
var element = document.getElementById(canvasId);
element.onmousemove = function(e) {
var xCoor = e.clientX;
var yCoor = e.clientY;
}
캔버스 내의 마우스 좌표는 event.offsetX 및 event.offsetY로 얻을 수 있습니다.여기 내 요점을 증명하는 작은 조각이 있다.
c=document.getElementById("c");
ctx=c.getContext("2d");
ctx.fillStyle="black";
ctx.fillRect(0,0,100,100);
c.addEventListener("mousemove",function(mouseEvt){
// the mouse's coordinates on the canvas are just below
x=mouseEvt.offsetX;
y=mouseEvt.offsetY;
// the following lines draw a red square around the mouse to prove it
ctx.fillStyle="black";
ctx.fillRect(0,0,100,100);
ctx.fillStyle="red";
ctx.fillRect(x-5,y-5,10,10);
});
body {
background-color: blue;
}
canvas {
position: absolute;
top: 50px;
left: 100px;
}
<canvas id="c" width="100" height="100"></canvas>
저는 매우 간단한 다른 솔루션을 구현했습니다. 그래서 여러분과 공유하려고 합니다.
그래서 문제는 마우스 커서가 드래그된 div가 0.0으로 점프한다는 것이었습니다.그래서 나는 divs의 새로운 위치를 조정하기 위해 div의 마우스 위치를 캡처해야 했다.
나는 PageX와 PageY를 읽고 이에 따라 의 상단과 좌측을 설정한 다음, div의 초기 위치에 커서를 유지하기 위한 좌표를 조정하기 위한 값을 얻기 위해 onDragStart 청취자를 사용하여 초기 트리거에만 제공되는 e.nativeEvent.layerX와 e.nativeEventlayerY를 mhouse 내에 저장합니다.e 드래그 가능한 div.
코드 예:
onDrag={(e) => {
let newCoords;
newCoords = { x: e.pageX - this.state.correctionX, y: e.pageY - this.state.correctionY };
this.props.onDrag(newCoords, e, item.id);
}}
onDragStart={
(e) => {
this.setState({
correctionX: e.nativeEvent.layerX,
correctionY: e.nativeEvent.layerY,
});
}
제가 겪었던 것과 같은 문제를 겪은 사람에게 도움이 되었으면 합니다.
function myFunction(e) {
var x = e.clientX - e.currentTarget.offsetLeft ;
var y = e.clientY - e.currentTarget.offsetTop ;
}
이거 잘 돼!
jQuery의 event.pageX 및 event.pageY를 jQuery의 메서드오프셋()과 함께 사용하면 요소에 상대적인 마우스 위치를 얻을 수 있습니다.
$(document).ready(function() {
$("#myDiv").mousemove(function(event){
var X = event.pageX - $(this).offset().left;
var Y = event.pageY - $(this).offset().top;
$(".cordn").text("(" + X + "," + Y + ")");
});
});
예를 다음에 나타냅니다.요소를 기준으로 마우스 위치를 찾는 방법
마우스 위치를 빠르게 가져오려면 다음 방법을 사용합니다.
Object.defineProperty(MouseEvent.prototype, "mouseX", {
get() {
return this.clientX - this.currentTarget.getBoundingClientRect().left;
}
});
Object.defineProperty(MouseEvent.prototype, "mouseY", {
get() {
return this.clientY - this.currentTarget.getBoundingClientRect().top;
}
});
예:
document.body.onmousemove=function(e){console.log(e.mouseX,e.mouseY)}
페이지 구조를 알아야 합니다. 캔버스가 디바의 자식이고 다른 디바의 자식이라면...그러면 이야기가 더 복잡해져요.2레벨의 divs 안에 있는 캔버스의 코드는 다음과 같습니다.
canvas.addEventListener("click", function(event) {
var x = event.pageX - (this.offsetLeft + this.parentElement.offsetLeft);
var y = event.pageY - (this.offsetTop + this.parentElement.offsetTop);
console.log("relative x=" + x, "relative y" + y);
});
원래 답은 iframe에 넣으라고 했어요.패딩이 0px로 설정된 캔버스에서 이벤트 offsetX 및 offsetY를 사용하는 것이 좋습니다.
<html>
<body>
<script>
var main=document.createElement('canvas');
main.width="200";
main.height="300";
main.style="padding:0px;margin:30px;border:thick dashed red";
document.body.appendChild(main);
// adding event listener
main.addEventListener('mousemove',function(e){
var ctx=e.target.getContext('2d');
var c=Math.floor(Math.random()*0xFFFFFF);
c=c.toString(16); for(;c.length<6;) c='0'+c;
ctx.strokeStyle='#'+c;
ctx.beginPath();
ctx.arc(e.offsetX,e.offsetY,3,0,2*Math.PI);
ctx.stroke();
e.target.title=e.offsetX+' '+e.offsetY;
});
// it worked! move mouse over window
</script>
</body>
</html>
@Patrick Boos 솔루션을 기반으로 하지만 중간 스크롤바의 잠재적인 문제를 해결합니다.
export function getRelativeCoordinates(event: MouseEvent, referenceElement: HTMLElement) {
const position = {
x: event.pageX,
y: event.pageY,
};
const offset = {
left: referenceElement.offsetLeft,
top: referenceElement.offsetTop,
};
let reference = referenceElement.offsetParent as HTMLElement;
while (reference) {
offset.left += reference.offsetLeft;
offset.top += reference.offsetTop;
reference = reference.offsetParent as HTMLElement;
}
const scrolls = {
left: 0,
top: 0,
};
reference = event.target as HTMLElement;
while (reference) {
scrolls.left += reference.scrollLeft;
scrolls.top += reference.scrollTop;
reference = reference.parentElement as HTMLElement;
}
return {
x: position.x + scrolls.left - offset.left,
y: position.y + scrolls.top - offset.top,
};
}
스크롤바가 있는 넓은 칸막이 안에서 커서 위치를 잡아야 했어요.목적은 요소를 div의 임의의 위치로 드래그하는 것이었습니다.
스크롤 깊숙한 곳에서 마우스 위치를 먼 곳에 둡니다.
$('.canvas').on('mousemove', function(e){
$(dragElement).parent().css('top', e.currentTarget.scrollTop + e.originalEvent.clientY );
$(dragElement).parent().css('left', e.currentTarget.scrollLeft + e.originalEvent.clientX )
});
예를 들어 선택사항이 있는 부모 요소에 추가한다면 얻을 수 있는 해결책을 찾지 못했기 때문입니다.
제가 한 일은 다음과 같습니다.
let positions = {
x: event.pageX,
y: event.pageY - event.currentTarget.getBoundingClientRect().top + event.currentTarget.offsetTop
}
여기 내가 얻은 게 있다.
$(".some-class").click(function(e) {
var posx = 0;
var posy = 0;
posx = e.pageX;
posy = e.pageY;
alert(posx);
alert(posy);
});
언급URL : https://stackoverflow.com/questions/3234256/find-mouse-position-relative-to-element
'source' 카테고리의 다른 글
PHP의 연결 풀링 (0) | 2023.01.22 |
---|---|
html에서 php를 사용하여 img src, title 및 alt를 추출하는 방법은 무엇입니까? (0) | 2023.01.22 |
mysql 데이터베이스의 사이즈는 어떻게 취득합니까? (0) | 2023.01.22 |
배열의 모든 값이 동일한지 확인합니다. (0) | 2023.01.12 |
Java split() 메서드는 마지막에 빈 문자열을 삭제합니까? (0) | 2023.01.12 |