तत्व के सापेक्ष माउस स्थिति का पता लगाएं


244

मैं कैनवास का उपयोग करके एक छोटा पेंटिंग ऐप बनाना चाहता हूं। इसलिए मुझे कैनवास पर माउस की स्थिति खोजने की आवश्यकता है।


2
पूर्ण समाधान: acko.net/blog/…
edA-qa mort-ora-y

3
मैं कितना कम प्यार करता हूं, लेकिन इस पोस्ट में सब कुछ समझाया गया है।
dwjohnston

यह वास्तव में पुराना है, लेकिन मैंने अभी हाल ही में एक GitHub प्रोजेक्ट शुरू किया है, जो अन्य चीजों के अलावा, ठीक वही है जो आपको चाहिए: brainlessdeveloper.com/mouse-move-interaction-spot-js
Fausto NA

जवाबों:


177

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प्रत्येक पंक्ति के लिए नहीं देखना पड़ता है ।

अपडेट करें

GetBoundingClientRect () का समर्थन करने वाले ब्राउज़रों के लिए नीचे @anytimecoder द्वारा एक नया, केवल-जावास्क्रिप्ट संस्करण है ।


7
क्या यह आपके लिए @ काम करता है, मैं एक "सही उत्तर" या एक टिप्पणी की सराहना करता हूं जो अभी भी आपके लिए काम नहीं कर रही है। शायद मैं आगे मदद कर सकूं।
स्पाइसस्पाइडर

8
जब तक आप बहुत सुस्त कोड नहीं चाहते हैं, तब तक किसी इवेंट हैंडलर में $ ('चयनकर्ता') का उपयोग करने से बचना चाहिए। अपने तत्व का चयन करें, और अपने हैंडलर में पहले से मौजूद संदर्भ का उपयोग करें। $ (विंडो) के लिए समान है कि एक बार और इसे कैश करें।
ऑस्टिन फ्रांस

2
यह एक आवश्यक उल्लेख नहीं है: यदि आप उपरोक्त कोड को कॉपी कर रहे हैं, तो सही var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();करने के लिए याद रखेंvar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
राज नाथानी

77
यह कैसे हो सकता है क्योंकि सवाल का jQuery से कोई लेना-देना नहीं है।
फ्लोरिअनबी

2
@ वापसी लेकिन कुछ लोग jquascript के बजाय jquascript में चीजें पूछते हैं क्योंकि jquery उनके वातावरण में संगत नहीं हो सकती है।
dbrree

307

जैसा कि मुझे एक 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.
}

पूर्ण उदाहरण का JSFiddle


2
इस विधि के साथ पूर्णांक मान सुनिश्चित करने के लिए आपको बाउंडिंग राउंड को गोल करना होगा।
जेक कोब

2
नए संपादन में स्क्रॉलिंग समस्याओं (क्लाइंटएक्स / वाई का उपयोग करके) को ठीक करना चाहिए
एरिक कोपामंस

6
इस जवाब को वोट देना चाहिए। शुक्रिया anytimecoder और @ErikKoopmans।
इवान

3
PSA: @mpen की टिप्पणी अप्रचलित है; यह विधि स्क्रॉल के मामलों में भी काम करती है। उनके
फिडेल

4
धन्यवाद! एक नोट: आप की जरूरत है e.currentTarget, नहीं e.target। अन्यथा, बच्चों के तत्व इसे प्रभावित करेंगे
मैक्सिम जॉरगिवस्क्य

60

निम्नलिखित कैनवास तत्व से संबंधित माउस पोजीशन की गणना करता है:

var example = document.getElementById('example'); 
example.onmousemove = function(e) { 
    var x = e.pageX - this.offsetLeft; 
    var y = e.pageY - this.offsetTop; 
}

इस उदाहरण में, thisको संदर्भित करता है exampleतत्व है, और eहै onmousemoveघटना।


83
हो सकता है कि यह मेरे लिए कोड की दो पंक्तियाँ हो जो "यह" अभाव संदर्भ का उपयोग करें?
डेरात्रियस

9
निश्चित रूप से संदर्भ की कमी है। 'ई' ईवेंट है और 'यह' वह एलिमेंट है, जो ईवेंट से जुड़ा है var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
निक बस्बी

22
यह काम नहीं करता है अगर कुछ वंशज तत्व रिश्तेदार या पूर्ण स्थिति का उपयोग करता है।
eda-qa मोर्ट-ओर-वाई

12
आप बाहर स्विच कर सकते हैं thisकरने के लिए e.currentTarget, कि आप तत्व है कि आप करने के लिए घटना श्रोता जोड़ा सापेक्ष स्थिति मिल जाएगा।
लिनस उन्नेबक जूल

2
यह तत्व के दृश्य भाग से संबंधित स्थिति को देता है , संपूर्ण तत्व को नहीं। क्या इसके लिए समायोजित करने का एक तरीका है अगर तत्व का हिस्सा व्यूपोर्ट में नहीं देखा जा सकता है और स्क्रॉलबार आदि हैं?
frabjous

37

शुद्ध जावास्क्रिप्ट में कोई जवाब नहीं है जो सापेक्ष निर्देशांक लौटाता है जब संदर्भ तत्व दूसरों के अंदर निहित होता है जो पूर्ण स्थिति के साथ हो सकता है। यहाँ इस परिदृश्य का हल है:

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,
  }; 

}

3
मुझे नहीं लगता कि यह खाता htmlतत्व ऑफसेट
एपिफ़िशबार्ट

3
स्क्रॉलिंग कंटेनर के साथ बढ़िया काम करता है, बस थोड़ा सा बदलाव के while(reference !== undefined)साथ : के साथ बदलें while(reference)। क्रोम में कम से कम, ऑफसेटपार्टेंट होने के नाते समाप्त नहीं होता है undefined, लेकिन null। बस देखना हो referenceहै truthy यह दोनों के साथ काम करता सुनिश्चित करेगा undefinedऔर null
blex

मैं एक और +1 देता अगर मैं कर सकता था, तो मुझे यह बताने की वजह से कि वहाँ एक offsetParentसंपत्ति है, जो अन्य स्थितियों में भी बहुत उपयोगी साबित होती है!
FonzTech

सामान्य तौर पर, अपरिभाषित के खिलाफ जांच करना आमतौर पर एक बुरा विचार है
जुआन मेंडेस

मुझे लगता है कि आपको स्क्रॉल किए गए वंशज को घटाना scrollLeftऔर scrollTopक्षतिपूर्ति करना होगा।
रॉबर्ट

20

इस समस्या की कठिनाई का एक अच्छा लेखन यहाँ पाया जा सकता है: http://www.quirksmode.org/js/events_properties.html#position

वहां वर्णित तकनीक का उपयोग करके आप दस्तावेज़ में पति-पत्नी की स्थिति पा सकते हैं। फिर आप बस यह देखने के लिए जांचें कि क्या यह आपके तत्व के बाउंडिंग बॉक्स के अंदर है, जिसे आप कॉल करके पा सकते हैं element.getBoundingClientRect()जो निम्नलिखित गुणों के साथ एक वस्तु वापस करेगा { bottom, height, left, right, top, width }:। वहाँ से यह पता लगाना तुच्छ है कि क्या आपके तत्व के अंदर भी हुआ था या नहीं।


1
अफसोस की बात है, यह विफल रहता है अगर वहाँ किसी भी तरह के रोटेशन चल रहा है
एरिक

17

मैंने इन सभी समाधानों की कोशिश की और एक मैट्रिक्स रूपांतरित कंटेनर (पैनज़ूम लाइब्रेरी) के साथ मेरे विशेष सेटअप के कारण काम नहीं किया। यह सही मान लौटाता है, भले ही ज़ूम और पैन किया गया हो:

mouseevent(e) {
 const x = e.offsetX,
       y = e.offsetY
}

लेकिन केवल अगर रास्ते में कोई बाल तत्व नहीं हैं। सीएसएस का उपयोग करके, उन्हें घटना के लिए 'अदृश्य' बनाकर इसे दरकिनार किया जा सकता है:

.child {
   pointer-events: none;
}

3
यह निश्चित रूप से 2019 में ऐसा करने का तरीका है। अन्य उत्तर सभी पुराने crufty सामान से भरे हुए हैं।
कॉलिन डी

1
@ColinD धन्यवाद! मैं जोड़ना भूल गया कि यह IE11 में भी काम करता है।
फेबियन वॉन एलर्ट्स

इसने मेरे लिए काम किया। हालांकि, मुझे संदेह है कि 1) कुछ अपवित्र 2) उच्च श्रेणी निर्धारण उत्तर अधिक जटिल हैं और 3) मुझे कोई कमियां नहीं बताई गई हैं। किसी को भी इस दृष्टिकोण का उपयोग करने के किसी भी कोन जानता है?
मार्क ई

1
@MarkE इसके बारे में कुछ भी संदिग्ध नहीं है। यह StackOverflow के कई दोषों में से एक है। जो जवाब आप शीर्ष पर देखते हैं, वे इस उत्तर के कई साल पहले यहां पोस्ट किए गए थे, इसलिए उन्होंने जबरदस्त वोट हासिल किया। एक बार जब कोई उत्तर इस गति को प्राप्त कर लेता है, तो उसे हराना बहुत कठिन और बहुत दुर्लभ होता है।
जैक गिफिन

9

मैं इस सवाल में आए, लेकिन इसे मेरे मामले के लिए काम करने के लिए में (एक डोम तत्व पर dragover का उपयोग कर (नहीं मेरे मामले में कैनवास) किया जा रहा है), मैंने पाया है कि आप केवल उपयोग करने के लिए है कि offsetXऔर offsetYdragover माउस घटना पर ।

onDragOver(event){
 var x = event.offsetX;
 var y = event.offsetY;
}

2
यह मेरे लिए बहुत अच्छा काम किया। किसी ने इसे क्यों नहीं उतारा? मुझे आश्चर्य है कि अगर कोई नुकसान हो। अगर मुझे कोई मिलता है तो मैं वापस रिपोर्ट करूँगा!
सीबास

7
event.offsetX उस तत्व के सापेक्ष है जो माउस पॉइंटर वर्तमान में खत्म हो गया है, न कि वह तत्व जिसके पास ड्रैगओवर श्रोता जुड़ा हुआ है। यदि आपके पास एक नेस्टेड तत्व संरचना नहीं है तो यह ठीक है, लेकिन यदि आप ऐसा करते हैं तो यह काम नहीं करेगा।
opsb

7

I +1 'मार्क वैन वाइक का जवाब, क्योंकि यह मुझे सही दिशा में मिला, लेकिन मेरे लिए इसे बहुत हल नहीं किया। मैं अभी भी एक और तत्व के भीतर निहित तत्वों में पेंटिंग पर एक ऑफसेट था।

फोलोइंग ने इसे मेरे लिए हल किया:

        x = e.pageX - this.offsetLeft - $(elem).offset().left;
        y = e.pageY - this.offsetTop - $(elem).offset().top;

दूसरे शब्दों में - मैं बस नेस्टेड सभी तत्वों से सभी ऑफसेट को ढेर कर दिया


आपके लिए +1! यह वह उत्तर है जिसकी मुझे तलाश है। मेरे पास दो कैनवस एक दूसरे के ऊपर ढेर थे और निर्देशांक अन्य विभाजनों के कारण सभी गलत थे। मुझे पता था कि यह समस्या थी, लेकिन इसकी भरपाई के लिए तर्क / समीकरण को नहीं जानता था। आपने मेरी समस्या भी ठीक कर दी! = D धन्यवाद!
9

5

उपर्युक्त उत्तरों में से कोई भी संतोषजनक 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

4

आपमें से जो नियमित वेबसाइट या PWAs (प्रोग्रेसिव वेब ऐप्स) विकसित कर रहे हैं, मोबाइल उपकरणों और / या लैपटॉप / टच स्क्रीन के साथ मॉनिटर के लिए, तो आप यहाँ आ गए हैं क्योंकि आप माउस इवेंट में उपयोग किए जा सकते हैं और टच के कभी-कभी दर्दनाक अनुभव के लिए नए हैं। घटनाओं ... याय!

सिर्फ 3 नियम हैं:

  1. घटनाओं mousemoveया touchmoveघटनाओं के दौरान जितना संभव हो उतना कम करें ।
  2. इवेंट्स mousedownया touchstartइवेंट्स के दौरान ज्यादा से ज्यादा करें ।
  3. हाइब्रिड डिवाइसों पर भी फायरिंग से माउस की घटनाओं को रोकने के लिए स्पर्श घटनाओं के लिए प्रसार को रोकें और चूक को रोकें।

कहने की जरूरत नहीं है, चीजें 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();
}
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">

3

आप इसे प्राप्त कर सकते हैं

var element = document.getElementById(canvasId);
element.onmousemove = function(e) {
    var xCoor = e.clientX;
    var yCoor = e.clientY;
}

क्या यह काम IE में होगा, या क्या IE अभी भी विंडो का उपयोग करता है। इस घटना को सुनने वाले के पहले तर्क तक पहुंचाने के बजाय? संपादित करें - मुझे लगता है कि IE में संस्करण 9 तक वैसे भी कैनवास तत्व का अभाव है, लेकिन यह शायद अभी भी IE का समर्थन करना चाहिए क्योंकि एक्वान्स जैसी चीजों के कारण ....
डग

21
यह ब्राउज़र विंडो के सापेक्ष निर्देशांक देगा, फिर भी यह पता लगाने की आवश्यकता होगी कि क्या वे तत्व का उपयोग कर रहे हैं ।getBoundingClientRect ()
डेविड डब्ल्यू कीथ

मुझे getBoundingClientRect से अवगत कराने के लिए धन्यवाद !!!! मुझे कभी महसूस नहीं हुआ कि ऐसी कोई बात थी!
गेरशोम

@ DavidW.Keith टिप्पणी को वास्तव में सही उत्तर माना जाना चाहिए!
उलरिक। S

3

इस ट्यूटोरियल से लिया गया , सुधार के साथ शीर्ष टिप्पणी के लिए धन्यवाद:

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 );
} );

3

मुझे पता है कि मुझे थोड़ी देर हो गई है, लेकिन यह PURE जावास्क्रिप्ट के साथ काम करता है, और यह आपको तत्व के भीतर पॉइंटर के निर्देशांक भी देता है यदि तत्व व्यूपोर्ट से बड़ा है और उपयोगकर्ता ने स्क्रॉल किया है।

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 html टैग के लिए ऋणात्मक होगा। हम इस संख्या का उपयोग तत्व और सामग्री क्षेत्र के बाईं ओर की दूरी की गणना करने के लिए करते हैं। साथ मेंelement_offset_x = element.getBoundingClientRect().left......;

सामग्री क्षेत्र से तत्व की दूरी जानना। event.clientXहमें व्यूपोर्ट से पॉइंटर की दूरी देता है। यह समझना महत्वपूर्ण है कि व्यूपोर्ट और कंटेंट क्षेत्र दो अलग-अलग इकाइयाँ हैं, अगर पेज स्क्रॉल हो जाए तो व्यूपोर्ट आगे बढ़ सकता है। इसलिए, अगर पेज स्क्रॉल किया जाता है, तब भी क्लाइंट X वही नंबर वापस करेगा।

इसकी भरपाई करने के लिए, हमें पॉइंटर (व्यूपोर्ट के सापेक्ष) की स्थिति, व्यूपोर्ट की एक्स स्थिति (सामग्री क्षेत्र के सापेक्ष) में जोड़ने की जरूरत है। व्यूपोर्ट के X स्थान के साथ पाया जाता है window.pageXOffset.


1
स्क्रॉल करने के बारे में सोचने वाले एकमात्र उत्तरदाता होने के लिए धन्यवाद। साथ ही y- अक्ष को जोड़ने के लिए अपने उत्तर को बदलने पर विचार करें।
frabjous

3

स्पाइडर के समाधान के आधार पर, मेरा गैर 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;
}

यह स्क्रॉलिंग और जूमिंग (जिस स्थिति में कभी-कभी यह लौटाता है) के साथ काम करता है।


मैं अपवोट करूंगा, लेकिन क्या पेज ऑफसेट के लिए माइनस साइन नहीं होना चाहिए? या तो वह, या दूसरे भाग के आसपास कोष्ठक?
क्रिस सुनमी

1

एक कैनवास के अंदर माउस निर्देशांक को 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 कैनवास ओवरलेइंग कर रहा है, जैसे @opsb ने कहा
डेविड पेइचो

1
canvas.onmousedown = function(e) {
    pos_left = e.pageX - e.currentTarget.offsetLeft;
    pos_top = e.pageY - e.currentTarget.offsetTop;
    console.log(pos_left, pos_top)
}

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नोड।

MouseEvent.pageX

pageXकेवल पढ़ने के लिए संपत्ति रिटर्न एक्स (क्षैतिज) पूरे दस्तावेज़ को घटना रिश्तेदार के पिक्सल में समन्वय। यह गुण पृष्ठ के किसी भी क्षैतिज स्क्रॉलिंग को ध्यान में रखता है।

MouseEvent.pageY

MouseEvent.pageYकेवल पढ़ने के लिए संपत्ति विवरणी वाई (ऊर्ध्वाधर) पूरे दस्तावेज़ को घटना रिश्तेदार के पिक्सल में समन्वय। यह गुण पृष्ठ के किसी भी ऊर्ध्वाधर स्क्रॉल को ध्यान में रखता है।

आगे की व्याख्या के लिए, कृपया मोज़िला डेवलपर नेटवर्क देखें:

https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageX https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/3Y https: // developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop


हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
पैट्रिक हुंड

मैं वास्तव में आशा करता हूं कि भविष्य में पाठकों के पास एक जेएस एपीआई है जो उनके लिए यह गणना करता है। ;-) यह शायद सबसे सरल, पूर्ण, आत्म-निहित जवाब है। आत्म-व्याख्यात्मक कोड टिप्पणी करना केवल विचलित करने वाला है।
lama12345

मैं स्पष्टीकरण के लिए पैट्रिक हंड का दूसरा अनुरोध करता हूं। मैं सीएसएस / जेएस विशेषज्ञ नहीं हूं, और उदाहरण के लिए, pageऔर offsetमेरे बीच के संबंधों के बारे में अधिक जानना मेरे लिए बहुत उपयोगी होगा। इस अनुरोध पर विचार करने के लिए धन्यवाद!
cxw

@ cxw ओके, आप अभी 2 वें डाउनवोट हैं (1 अपवोट था) ... मैंने अब एक लंबा स्पष्टीकरण जोड़ा, यह 10x के समान है जब तक कि कोड की 4 लाइनें। आपका स्वागत है, पढ़कर मज़ा आया। मैंने आपके अनुरोध पर विचार किया! : p
lama12345

1
@ cxw मैंने एक अतिरिक्त निरपेक्ष स्थिति को जोड़कर और कैनवास के तत्व को ऑफ़स्क्रीन aswell के साथ जोड़कर गड़बड़ कर दिया है, इसलिए मुझे इसे स्क्रॉल करना पड़ा, जैसे बाएं / शीर्ष 2000px ऑफ़स्क्रीन। इस कोड को तोड़ने के लिए नहीं मिला।
लामा12345

1

मैंने एक अन्य समाधान लागू किया है जो मुझे लगता है कि बहुत सरल है इसलिए मैंने सोचा कि मैं आप लोगों के साथ साझा करूंगा।

तो, मेरे लिए समस्या यह थी कि घसीट दिया हुआ माउस माउस कर्सर के लिए 0,0 में कूद जाएगा । इसलिए मुझे div पर स्थिति को पकड़ने के लिए div को नई स्थिति को समायोजित करने की आवश्यकता थी।

मैंने divs PageX और PageY को पढ़ा और उसके अनुसार सबसे ऊपर और बाईं ओर सेट किया और फिर निर्देश प्राप्त करने के लिए कि मैं div पर एक प्रारंभिक स्थिति में कर्सर रखने के लिए निर्देशांक समायोजित करने के लिए एक onDragStart श्रोता का उपयोग करता हूं और e.nativeEvent को स्टोर करता हूं .layerX और e.nativeEvent.layerY है कि केवल शुरुआती ट्रिगर में आपको ड्रैग करने योग्य डिव के भीतर पति - पत्नी की स्थिति मिलती है।

उदाहरण कोड:

 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,
            });
          }

मुझे आशा है कि यह किसी को उसी समस्या से गुजरने में मदद करेगा जो मैं गया था :)


1
function myFunction(e) {
    var x =  e.clientX - e.currentTarget.offsetLeft ; 
    var y = e.clientY - e.currentTarget.offsetTop ;
}

यह ठीक काम करता है!


0

आपको अपने पृष्ठ की संरचना को जानना होगा, क्योंकि यदि आपका कैनवास एक div का एक बच्चा है, जो बदले में एक अन्य div का बच्चा है ... तो कहानी अधिक जटिल हो जाती है। यहाँ एक कैनवास के लिए मेरा कोड है जो div s के 2 स्तरों के अंदर है:

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);

});


0

मूल उत्तर ने कहा कि यह एक iframe में डाल दिया। बेहतर समाधान यह है कि घटनाओं को एक कैनवस पर ऑफसेट एक्सएक्सएक्स और ऑफसेट का उपयोग किया जाए जिसमें 0px पर पैडिंग सेट है।

<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>

0

यह है जो मुझे मिला।

    $(".some-class").click(function(e) {

    var posx = 0;
    var posy = 0;

    posx = e.pageX;
    posy = e.pageY;

    alert(posx);
    alert(posy);
});

0

आप माता-पिता 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)
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.