উপাদানটির সাথে সম্পর্কিত মাউস অবস্থানটি সন্ধান করুন


244

আমি ক্যানভাস ব্যবহার করে একটি সামান্য পেইন্টিং অ্যাপ তৈরি করতে চাই। সুতরাং আমার ক্যানভাসে মাউসের অবস্থানটি সন্ধান করা উচিত।


2
সম্পূর্ণ সমাধান: acko.net/blog/…
এডিএ-কিএ মার্ট-ওরা-ই

3
আমি কত সংক্ষিপ্ত ভালবাসি, তবে এই পোস্টটি সমস্ত কিছু ব্যাখ্যা করে।
দ্বিজোহনস্টন

এটি সত্যই পুরানো, তবে আমি সবেমাত্র একটি গিটহাব প্রকল্প শুরু করেছি যা অন্যান্য জিনিসগুলির মধ্যে আপনার প্রয়োজন মতো ঠিক করে তোলে
Fausto NA

উত্তর:


177

জিকিউরি ব্যবহার করা লোকদের জন্য:

কখনও কখনও, যখন আপনি নেস্টেড উপাদানগুলি রাখেন, ইভেন্টের সাথে এর মধ্যে একটি সংযুক্ত থাকে, আপনার ব্রাউজারটি পিতামাতার হিসাবে কী দেখবে তা বুঝতে বিভ্রান্তিকর হতে পারে। এখানে, আপনি কোন পিতামাতার নির্দিষ্ট করতে পারেন।

আপনি মাউস অবস্থানটি গ্রহণ করেন এবং তারপরে এটি প্যারেন্ট এলিমেন্টের অফসেট অবস্থান থেকে বিয়োগ করুন।

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;

এইভাবে, জিকুয়েরিকে #elementপ্রতিটি লাইনের সন্ধান করতে হবে না ।

হালনাগাদ

GetBoundingClientRect () সমর্থন করে ব্রাউজারগুলির জন্য নীচে @ এনটাইমকোডার দ্বারা একটি নতুন, জাভাস্ক্রিপ্ট-কেবলমাত্র সংস্করণ রয়েছে ।


7
এটি আপনার পক্ষে @ বেন হয়ে কাজ করেছে, আমি একটি "সঠিক উত্তর" বা এখনও আপনার জন্য কী কাজ করছে না তার একটি মন্তব্যকে প্রশংসা করব। আমি আরও সাহায্য করতে পারেন।
স্পার্কস্পাইডার

8
ইভেন্ট হ্যান্ডলারে $ ('নির্বাচক') ব্যবহার করা এড়ানো উচিত, যদি না আপনি খুব আলস্য কোড চান। আপনার উপাদানটি প্রাক-নির্বাচন করুন এবং আপনার হ্যান্ডলারের পূর্বনির্ধারিত রেফারেন্সটি ব্যবহার করুন। $ (উইন্ডো) এর জন্য একই কাজ করুন এবং এটি ক্যাশে করুন।
অস্টিন ফ্রান্স

2
এই একটি প্রয়োজনীয় উল্লেখ নয়: যদি আপনি উপরের কোড পেস্ট কপি করা হয়, সংশোধন মনে রাখবেন var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();থেকেvar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
রাজ Nathani

77
যেভাবে উত্তরটি হতে পারে যেহেতু প্রশ্নের jQuery এর সাথে কোনও সম্পর্ক নেই?
ফ্লোরিয়ানবি

2
@ ব্ল্যাক তবে কিছু লোক jquery এর পরিবর্তে জাভাস্ক্রিপ্টে জিনিস জিজ্ঞাসা করেছেন কারণ jquery তাদের পরিবেশে সামঞ্জস্য হতে পারে না।
dbrree

307

যেহেতু আমি কোনও জিকিউরি-মুক্ত উত্তর খুঁজে পাইনি যে আমি অনুলিপি / পেস্ট করতে পারি, আমি এখানে সমাধানটি ব্যবহার করেছি:

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

পুরো উদাহরণের জেএসফিডাল


2
আপনাকে করার প্রয়োজন সীমান্ত RECT সুসম্পন্ন এই পদ্ধতিতে মান পূর্ণসংখ্যা নিশ্চিত করতে হবে।
জ্যাক কোব

2
নতুন সম্পাদনায় স্ক্রোলিংয়ের সমস্যাগুলি সমাধান করা উচিত (ক্লায়েন্টএক্স / ওয়াই ব্যবহার করে)
এরিক কোপম্যানস

6
এই উত্তরটি ভোট দেওয়া উচিত। আপনাকে যে কোনও সময়কোডার এবং @ এরিককোপম্যানসকে ধন্যবাদ।
ইভান

3
পিএসএ: @ স্পেনের মন্তব্য অপ্রচলিত; এই পদ্ধতিটি এমনকি স্ক্রোলিংয়ের ক্ষেত্রেও কাজ করে। তাদের ফিডলের
জারলি

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ইভেন্ট is


83
হতে পারে এটি আমি কিন্তু দুটি লাইনের কোড যা "এই" শব্দটির কীওয়ার্ড ব্যবহার করে?
ডেরেট্রিয়াস

9
অবশ্যই প্রসঙ্গের অভাব রয়েছে। 'ই' ইভেন্ট এবং 'এটি' হ'ল ইভেন্টটি যে উপাদানটির সাথে বাঁধা আছে var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
নিক বিসবি

22
যদি কোনও বংশধর উপাদান আপেক্ষিক বা পরম অবস্থান ব্যবহার করে তবে এটি কাজ করে না।
এডিএ-কিএ মার্ট-ওরা-ই

12
আপনি খুঁজে সুইচ করতে পারেন thisথেকে e.currentTarget, আপনি উপাদান যে আপনি ঘটনা শ্রোতা যোগ অবস্থান আপেক্ষিক পাবেন।
লিনাস আনবেনব্যাক

2
এটি পুরো উপাদানটি নয়, উপাদানটির দৃশ্যমান অংশের সাথে অবস্থানটি সম্পর্কিত বলে মনে হচ্ছে । ভিউপোর্টে যদি উপাদানটির কিছু অংশ দেখতে না পাওয়া যায় এবং সেখানে স্ক্রোলবারগুলি থাকে তবে এর জন্য উপযুক্ত হওয়ার কোনও উপায় আছে কি?
উদ্ভট

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উপাদানটিকে অফসেটে গ্রহণ করে
apieceofbart

3
প্রতিস্থাপন করুন: স্ক্রলিং পাত্রে, শুধু একটু পরিবর্তনের সঙ্গে সাথে সুন্দরভাবে কাজ করে while(reference !== undefined)দিয়ে while(reference)। কমপক্ষে ক্রোমে, অফসেট প্যারেন্টটি শেষ হয় না undefined, তবে null। শুধু চেক কিনা referenceহয় truthy এটি উভয় সঙ্গে কাজ করে নিশ্চিত করবে undefinedএবং null
ব্লেক্স

আমি যদি পারতাম তবে আমি অন্য +1 দিতাম, কারণ এখানে এমন একটি offsetParentসম্পত্তি রয়েছে যা আমাকে জানানোর কারণে , যা অন্যান্য পরিস্থিতিতেও খুব কার্যকর বলে প্রমাণিত হয়!
ফোনজটেক

সাধারণভাবে, অপরিজ্ঞাত বিরুদ্ধে চেক করা সাধারণত একটি খারাপ ধারণা
হুয়ান মেন্ডেস

আমি মনে করি আপনাকে বিয়োগ করা উচিত scrollLeftএবং scrollTopস্ক্রোলড বংশধরদের ক্ষতিপূরণ দিতে হবে।
রবার্ট

20

এই সমস্যার অসুবিধা সম্পর্কে একটি ভাল লেখাগুলি এখানে পাওয়া যাবে: http://www.quirksmode.org/js/events_properties.html# অবস্থান

সেখানে বর্ণিত কৌশলটি ব্যবহার করে আপনি নথিতে মাউসের অবস্থানটি খুঁজে পেতে পারেন। তারপর আপনি শুধু এটি আপনার উপাদান, যা আপনি কলিং দ্বারা জানতে পারেন সীমান্তবর্তী বক্সের ভিতরে রয়েছে কিনা তা পরীক্ষা 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 এ করার উপায় The অন্যান্য উত্তরগুলি সমস্ত পুরানো ক্রুফিটী ব্যাগেজ সহ বোঝাই।
কলিন ডি

1
@ কলিনড আপনাকে ধন্যবাদ! আমি যোগ করতে ভুলে গেছি এটি আইই 11 এও কাজ করে।
ফ্যাবিয়ান ভন এলার্টস

এটি আমার পক্ষে কাজ করেছে। যাইহোক, আমি সন্দেহজনক যে 1) কয়েকটি আপোড 2) উচ্চতর রেট করা উত্তরগুলি আরও জটিল এবং 3) আমি কোনও ত্রুটি ব্যাখ্যা করে দেখছি না। এই পদ্ধতির ব্যবহার সম্পর্কে কেউ কি কোন কৌশল জানতে পারে?
মার্ক ই ই

1
@ মার্ক এটি সম্পর্কে সন্দেহজনক কিছুই নেই। এটি স্ট্যাকওভারফ্লোয়ের অনেকগুলি ত্রুটিগুলির মধ্যে একটি। আপনি যে উত্তরগুলি শীর্ষে দেখছেন তারা এই উত্তরটির বহু বছর আগে এখানে পোস্ট করা হয়েছিল, তাই তারা আপ-ভোটের গতিবেগ অর্জন করেছে। কোনও উত্তর একবার এই গতি অর্জন করার পরে, এটি হারানো বেশ শক্ত এবং বেশ বিরল।
জ্যাক গিফিন

9

আমি এই প্রশ্নের জুড়ে এসেছিল, কিন্তু যাতে এটা আমার ক্ষেত্রে কাজ করার জন্য (একটি DOM-উপাদানের উপর dragover ব্যবহার (না আমার ক্ষেত্রে ক্যানভাস) হচ্ছে), আমি দেখেছি আপনি শুধুমাত্র ব্যবহার করতে হবে আছে offsetXএবং offsetYdragover-মাউস ইভেন্টে ।

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

2
এটি আমার জন্য কাজ করে মহান. কেন কেউ এটিকে উত্থাপন করেনি? আমি ভাবছি যদি কোনও অসুবিধা হয় কিনা। আমি যদি কিছু পাই তবে আমি রিপোর্ট করব!
সমুদ্রপথ

7
ইভেন্ট.অফসেটএক্স বর্তমানে যে উপাদানটির সাথে মাউস পয়েন্টারটি শেষ হয়েছে তার সাথে সম্পর্কিত, ড্রাগের সাথে শ্রোতার সংযুক্তিযুক্ত উপাদানটি নয়। আপনার যদি নেস্টেড উপাদান কাঠামো না থাকে তবে এটি ঠিক আছে, তবে আপনি যদি এটি করেন তবে এটি কার্যকর হবে না।
opsb

7

আমি +1 'মার্ক ভ্যান উইকের উত্তরটি আমাকে সঠিক দিকে নিয়ে যাওয়ার কারণে, তবে এটি আমার পক্ষে বেশিরভাগ সমাধান হয়নি। আমি এখনও অন্য উপাদানের মধ্যে থাকা উপাদানগুলিতে পেইন্টিংয়ের একটি অফসেট রেখেছিলাম।

আমার জন্য এটি সমাধান করা:

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

অন্য কথায় - আমি খুব সহজেই সমস্ত উপাদান থেকে নেস্টেড সমস্ত অফসেট স্ট্যাক করেছি


আপনার জন্য +1! এই উত্তরটি আমি খুঁজছি। আমার একে অপরের উপরে দুটি ক্যানভ্যাস স্ট্যাক করা ছিল এবং অন্যান্য ডিভগুলির কারণে স্থানাঙ্কগুলি সবই ভুল ছিল। আমি জানতাম এটি সমস্যা, তবে এটির ক্ষতিপূরণ দেওয়ার যুক্তি / সমীকরণ জানতাম না। তুমিও আমার সমস্যা ঠিক করেছ! = ডি ধন্যবাদ!
পার্টাক

5

উপরের উত্তরগুলির মধ্যে কোনও সন্তোষজনক আইএমও নয়, তাই আমি যা ব্যবহার করি তা এখানে:

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

এবং যদি আপনাকে পৃষ্ঠার বর্তমান ওয়াই স্ক্রোলিং অবস্থানটি জানতে প্রয়োজন:

var yscroll = window.pageYOffset
        || (document.documentElement && document.documentElement.scrollTop)
        || document.body.scrollTop; // scroll Y position in page

4

আপনার মধ্যে যারা নিয়মিত ওয়েবসাইট বা পিচডাব্লুএ (প্রগ্রেসিভ ওয়েব অ্যাপস) মোবাইল ডিভাইস এবং / বা ল্যাপটপগুলি / টাচ স্ক্রিনযুক্ত মনিটরের জন্য বিকাশ করে থাকেন, আপনি এখানে চলে এসেছেন কারণ আপনি মাউস ইভেন্টগুলিতে অভ্যস্ত হতে পারেন এবং মাঝে মাঝে স্পর্শের বেদনাদায়ক অভিজ্ঞতার ক্ষেত্রে নতুন হন ঘটনা ... হ্যাঁ!

এখানে মাত্র 3 টি বিধি রয়েছে:

  1. ইভেন্ট mousemoveবা touchmoveইভেন্টের সময় যতটা সম্ভব সম্ভব করুন Do
  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 ব্যবহার পছন্দ করেন ? আমি করি! তারপরে আপনার এইচটিএমএল দেখতে এমন হবে:

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

আইআই-তে এটি কাজ করবে, বা আইই এখনও শ্রোতার প্রথম যুক্তিতে ইভেন্টটি প্রেরণের পরিবর্তে উইন্ডো.ভেন্ত ব্যবহার করবে? সম্পাদনা করুন - আমার ধারণা আই 9 এর 9 ম সংস্করণ পর্যন্ত ক্যানভাস উপাদানটির অভাব রয়েছে তবে এক্সানভান্সের মতো জিনিসের কারণে এটি সম্ভবত আইই সমর্থন করবে ....
ড্যাগ ন্যাবিট

21
এটি ব্রাউজার উইন্ডোটির তুলনায় স্থানাঙ্কগুলি দেবে, তবুও তারা উপাদানটি ব্যবহার করে উপাদানটিতে রয়েছে কিনা তা এখনও খুঁজে বের করতে হবে getgetBoundingClientRect ()
ডেভিড ডব্লু। কিথ

আমাকে getBoundingClientRect সম্পর্কে সচেতন করার জন্য আপনাকে ধন্যবাদ !!!! আমি বুঝতে পারি না এমন একটা জিনিস আছে!
গেরশম

@ ডেভিডডাব্লু। কিথ মন্তব্যটি সত্যই সঠিক উত্তর হিসাবে বিবেচনা করা উচিত!
উলরিক। এস

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

আমি বুঝতে পেরেছি যে আমি কিছুটা দেরি করেছি তবে এটি শুদ্ধ জাভাস্ক্রিপ্টের সাথে কাজ করে এবং যদি উপাদানটি ভিউপোর্টের চেয়ে বড় হয় এবং ব্যবহারকারী স্ক্রোল করে থাকে তবে এটি আপনাকে উপাদানটির মধ্যে পয়েন্টারের স্থানাঙ্কগুলিও দেয়।

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

কিভাবে এটা কাজ করে.

আমরা প্রথম কাজটি হ'ল বর্তমান ভিউপোর্টের সাথে সম্পর্কিত এইচটিএমএল উপাদানগুলির (সামগ্রীর ক্ষেত্রের) অবস্থান। পৃষ্ঠাটিতে যদি স্ক্রোলবার থাকে এবং স্ক্রল হয়, তবে getBoundingClientRect().leftএইচটিএমএল ট্যাগের জন্য ফিরে আসা সংখ্যাটি নেতিবাচক হবে। তারপরে আমরা এই নম্বরটি উপাদান এবং উপাদান বামের মধ্যে দূরত্ব গণনা করতে ব্যবহার করি। সঙ্গেelement_offset_x = element.getBoundingClientRect().left......;

সামগ্রী অঞ্চল থেকে উপাদানটির দূরত্ব জানা Know event.clientXআমাদের ভিউপোর্ট থেকে পয়েন্টারের দূরত্ব দেয়। এটি বোঝা গুরুত্বপূর্ণ যে ভিউপোর্ট এবং সামগ্রীর ক্ষেত্র দুটি পৃথক সত্তা, পৃষ্ঠাটি স্ক্রল করা থাকলে ভিউপোর্টটি স্থানান্তর করতে পারে। অতএব, ক্লায়েন্টএক্স পৃষ্ঠা স্ক্রল করা থাকলেও একই নম্বরটি ফিরিয়ে দেবে।

এর ক্ষতিপূরণ দিতে আমাদের পয়েন্টারের x অবস্থান (ভিউপোর্টের তুলনায়), ভিউপোর্টের এক্স পজিশনে (বিষয়বস্তুর সাথে সম্পর্কিত অঞ্চল) যুক্ত করতে হবে। সাথে ভিউপোর্টের এক্স অবস্থানটি পাওয়া যায় window.pageXOffset.


1
স্ক্রোলিং সম্পর্কে চিন্তা করার একমাত্র উত্তরদাতা হওয়ার জন্য আপনাকে ধন্যবাদ। Y- অক্ষগুলি যুক্ত করতে নিজের উত্তর পরিবর্তন করার বিষয়টি বিবেচনা করুন।
উদ্ভট

3

@ স্পাইডারের সমাধানের ভিত্তিতে, আমার নন জিকুয়ের সংস্করণটি এটি:

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

এটি স্ক্রোলিং এবং জুমিং (উভয় ক্ষেত্রে কখনও কখনও এটি ভাসা ফিরে আসে) নিয়ে কাজ করে।


আমি upvote হবে, কিন্তু সেগুলি পৃষ্ঠা অফসেটের জন্য বিয়োগ চিহ্ন হওয়া উচিত নয়? হয় না, বা দ্বিতীয় অংশের কাছাকাছি?
ক্রিস সুনামি

1

একটি ক্যানভাসের মাউস স্থানাঙ্কগুলি ইভেন্ট.অফসেটএক্স এবং ইভেন্ট.অফসেটওয়াইয়ের জন্য ধন্যবাদ পেতে পারে। আমার বক্তব্যটি প্রমাণ করার জন্য এখানে একটি ছোট স্নিপেট রয়েছে:

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>
    


অন্য ডিভ যদি ক্যানভাসকে উপচে ফেলে তবে এটি কাজ করে না, ঠিক যেমন @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/pageY https: // বিকাশকারী.মোজিলা.আর.ইন.ইউএস / ডকস / ওয়েবে / এপিআই / এইচটিএমলেলেট / অফসেট লেফট https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop


যদিও এই কোড স্নিপেট একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে, সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না।
প্যাট্রিক হুন্ড

আমি সত্যিই আশা করি ভবিষ্যতে পাঠকদের একটি জেএস এপিআই রয়েছে যা তাদের জন্য এটি গণনা করে। ;-) এটি সম্ভবত সবচেয়ে সহজ, পূর্ণ, স্বয়ংসম্পূর্ণ উত্তর। স্ব-ব্যাখ্যামূলক কোডের মন্তব্য করা কেবল বর্জ্যকে বিভ্রান্ত করছে।
lama12345

আমি প্যাট্রিকহুন্ডের দ্বিতীয় বিবরণটি ব্যাখ্যা করার জন্য করছি। আমি কোনও সিএসএস / জেএস বিশেষজ্ঞ নই, এবং এর মধ্যে সম্পর্কগুলি সম্পর্কে আরও জানার উদাহরণস্বরূপ, pageএবং offsetএটি আমার পক্ষে খুব সহায়ক হবে। এই অনুরোধ বিবেচনা করার জন্য আপনাকে ধন্যবাদ!
cxw

@ সিএক্সডাব্লু ঠিক আছে, আপনি এখন ২ য় ডাউনভোট (যার 1 টি upvote ছিল) ... আমি এখন একটি দীর্ঘ ব্যাখ্যা যুক্ত করেছি, এটি কোডের 4 লাইনের মতো 10x এর মতো। আপনি স্বাগত, পড়া মজা। আমি আপনার অনুরোধ বিবেচনা! : পি
লামা 12345

1
@ সিএক্সডাব্লু আমি অতিরিক্ত নিখুঁত অবস্থানযুক্ত উপাদান যুক্ত করে এবং ক্যানভাস উপাদানটি নিজেই অফস্ক্রিনকে জোর করে জড়িয়ে পড়েছি, সুতরাং আমাকে বাম / শীর্ষ 2000px অফস্ক্রিনের মতো স্ক্রোল করতে হয়েছিল। এই কোডটি ভাঙ্গতে পারেনি।
lama12345

1

আমি অন্য একটি সমাধান কার্যকর করেছি যা আমি মনে করি খুব সহজ তাই আমি ভেবেছিলাম আপনার সাথে ভাগ করে নিই।

সুতরাং, আমার জন্য সমস্যাটি হ'ল টানানো ডিভটি মাউস কার্সারের জন্য 0,0 এ চলে যাবে । সুতরাং আমার ডিভগুলিতে নতুন অবস্থানের সামঞ্জস্য করার জন্য ডিউজে মাউসগুলির অবস্থান ক্যাপচার করতে হবে।

আমি ডিভস পেজএক্সএক্স এবং পেজওয়াই পড়ি এবং তার অনুসারে উপরের এবং বামটি সেট করে এবং তারপরে ডিভিআরটিতে কার্সারটিকে প্রাথমিক অবস্থানে রাখার জন্য স্থানাঙ্কগুলি সমন্বয় করার জন্য মানগুলি পেতে আমি একটি অনড্রাগস্টার্ট শ্রোতার ব্যবহার করি এবং 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

আপনাকে আপনার পৃষ্ঠার কাঠামোটি জানতে হবে, কারণ যদি আপনার ক্যানভাসটি কোনও ডিভের বাচ্চা হয় যা পরিবর্তে অন্য ডিভের সন্তান হয় ... তবে গল্পটি আরও জটিল হয়ে উঠবে। ক্যানভাসের জন্য আমার কোডটি যা ডিভের 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

মূল উত্তরটি এটি একটি ইফ্রেমে রাখার জন্য বলেছে। আরও ভাল সমাধান হল ইভেন্টগুলি অফসেটএক্স এবং অফসেটওয়াইকে একটি ক্যানভাসে ব্যবহার করা যা প্যাডিংটি 0 পিক্সে সেট করে।

<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)
})
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.