ब्राउज़र विंडो के सापेक्ष HTML तत्व की स्थिति (X, Y) को पुनः प्राप्त करें


1562

मैं इस तरह के रूप एक्स और HTML तत्वों की Y स्थिति पाने के लिए जानना चाहता हूँ imgऔर divब्राउज़र विंडो के लिए जावास्क्रिप्ट सापेक्ष में।


134
किस से संबंधित?
एंथनीवजोन

4
मैं कोड की इन 7 पंक्तियों का उपयोग कर रहा था, जो कि सभी ब्राउज़रों में काम करता है I5,6,7 में विसंगतियों के साथ काम करता है (मुझे याद नहीं था कि कोई प्रूबम ... डॉक प्रकार हो सकता है) ... quirksmode.org/js/findpos। html और मैं इतने सालों से इसका बहुत उपयोग कर रहे थे। हो सकता है कि किसी को दोष हो, यदि कोई हो
जयपाल चंद्रन

98
@AnthonyWJones, मुझे लगता है कि आपको पांडित्यपूर्ण आनंद की आवश्यकता थी, लेकिन यह स्पष्ट है, क्योंकि यह हमेशा होता है जब अनिर्दिष्ट, कि ओपी सबसे सामान्य मामले को संदर्भित करता है, या ब्राउज़र के विंडो निर्देशांक को संदर्भित करता है।
Motes

7
@ मत, नहीं, यह स्पष्ट नहीं है। अनुमान, विषय और झूठ के स्वयंसिद्धों को एक तरफ छोड़ दें। यह पृष्ठ के व्यूपोर्ट या टॉप (उर्फ डॉक्यूमेंट.डॉटकॉममेंट ईमेंट) के सापेक्ष हो सकता है।
आंद्रे फिगयेरिडो

15
सबसे सामान्य के लिए डिफॉल्ट नहीं है, यह तार्किक प्रगति है, इसलिए यह खिड़की के सापेक्ष होगा, या "शीर्ष पृष्ठ" शब्द हो सकता है जैसा कि आप इसे डालते हैं। गेम थ्योरी में, इसे एक अवधारणा के रूप में कोडित किया गया है जिसे स्कैशिंग बिंदु कहा जाता है। यह निर्दिष्ट करना सुनिश्चित करें कि आपके पास सबसे सामान्य मामला नहीं है।
Motes

जवाबों:


1792

सही दृष्टिकोण का उपयोग करना है element.getBoundingClientRect():

var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);

जब तक आप इसकी देखभाल करने की संभावना रखते हैं तब तक Internet Explorer ने इसका समर्थन किया है और इसे CSSOM व्यू में अंतिम रूप से मानकीकृत किया गया है । अन्य सभी ब्राउज़रों ने इसे बहुत पहले अपनाया था

कुछ ब्राउज़र ऊँचाई और चौड़ाई के गुण भी लौटाते हैं, हालांकि यह गैर-मानक है। यदि आप पुराने ब्राउज़र संगतता के बारे में चिंतित हैं, तो एक अनुकूलित अपमानजनक कार्यान्वयन के लिए इस उत्तर के संशोधन की जाँच करें।

द्वारा लौटाए गए मूल्य element.getBoundingClientRect()व्यूपोर्ट के सापेक्ष हैं। यदि आपको किसी अन्य तत्व के सापेक्ष इसकी आवश्यकता है, तो बस एक आयत को दूसरे से घटाएँ:

var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;

alert('Element is ' + offset + ' vertical pixels from <body>');

143
जेएस पर एक बहुत ही दिलचस्प लेख निर्देशांक । यह लेख SO पर कहीं भी उल्लिखित है, यह चाहिए ..
e2-e4

6
काम नहीं करता है ... यह शरीर में 8px मार्जिन के कारण लंबवत और क्षैतिज रूप से 8 पिक्सेल है। मेव का समाधान पूरी तरह से काम करता है। यदि आप चाहते हैं कि मेरे पास समस्या का प्रदर्शन करने के लिए एक छोटा परीक्षण है।
CpnCrunch

3
वास्तव में, मुझे लगता है कि यह निर्भर करता है कि आप वास्तव में क्या चाहते हैं। सवाल थोड़ा अस्पष्ट है। यदि आप सिर्फ व्यूपोर्ट के सापेक्ष कॉर्डर्स या बॉडी एलिमेंट के सापेक्ष चाहते हैं तो आपका उत्तर सही है, लेकिन यह उस मामले में आपकी मदद नहीं करता है, जहां आप तत्व की पूर्ण स्थिति चाहते हैं (जो मुझे लगता है कि ज्यादातर लोग चाहते हैं) । meouw का उत्तर आपको वह नहीं देता, जब तक कि आप '-scrollLeft' और '-scrollTop' बिट्स को हटा नहीं देते।
17 अक्टूबर को CpnCrunch

4
@CpnCrunch: मैं देख रहा हूं कि अब आपका क्या मतलब है; मुझे नहीं पता था कि आप मेरे उत्तर के उत्तरार्द्ध का जिक्र कर रहे हैं। जब शरीर में एक मार्जिन होता है, तो इसका बाउंडिंग बॉक्स प्रत्येक संबंधित पक्ष पर पिक्सेल की संख्या से ऑफसेट होगा। उस स्थिति में, आपको शरीर के निर्देशांक से गणना की गई मार्जिन शैली को घटाना होगा। यह ध्यान देने योग्य है कि सीएसएस रीसेट मार्जिन को हटा देता है <body>, हालांकि।
एंडी ई

3
element.getBoundingClientRect().topposition: fixedआईओएस (आईफोन 8) में एक तत्व के मामले में सही शीर्ष ऑफसेट वापस नहीं आता है यदि इसमें एक केंद्रित इनपुट तत्व होता है और वर्चुअल कीबोर्ड धीमा हो जाता है। उदाहरण के लिए, यदि विंडो के शीर्ष से वास्तविक ऑफसेट 200px है, तो यह 420px के रूप में रिपोर्ट करेगा, जहां 220px वर्चुअल कीबोर्ड की ऊंचाई है। यदि आप एलिमेंट सेट करते हैं position: absoluteऔर इसे उसी स्थिति में रखते हैं जैसे कि तय किया गया है, तो आपको सही 200px मिलेगा। मैं इसका कोई हल नहीं जानता।
जानिस एल्मरिस

327

किसी तत्व के लिए सटीक ऑफसेट प्राप्त करने के लिए लाइब्रेरी कुछ लंबाई तक जाती हैं।
यहाँ एक सरल कार्य है जो हर परिस्थिति में काम करता है जो मैंने कोशिश की है।

function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft - el.scrollLeft;
        _y += el.offsetTop - el.scrollTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}
var x = getOffset( document.getElementById('yourElId') ).left; 

14
परिवर्तन: el = el.parentNode to: el = el.offsetParent; और यह नेस्टेड आइफ्रेम्स के लिए काम करने लगता है ... मैं सोच रहा हूँ कि आपका क्या इरादा है?
एडम

4
यह समाधान अधूरा है। एक डिव पर एक मोटी सीमा लगाने की कोशिश करें और इसे कुछ बार घोंसला दें। फ़ायरफ़ॉक्स (2-5) के किसी भी संस्करण में यह सीमा चौड़ाई (एस) (यहां तक ​​कि मानकों के अनुपालन मोड में) द्वारा बंद हो जाएगा।
ck_

3
एक el.totalOffsetLeft और TotalOffsetTop फ़ंक्शन की तरह, ऐसा करने के लिए कोई क्लीनर तरीका नहीं है? jQuery के पास निश्चित रूप से यह विकल्प है, लेकिन यह शर्म की बात है कि इसके लिए कोई आधिकारिक तरीका नहीं है, क्या हमें DOM4 की प्रतीक्षा करने की आवश्यकता है? मैं एक HTML5 कैनवस एप्लिकेशन बना रहा हूं, इसलिए मुझे लगता है कि आइफ्रेम में कैनवस एलिमेंट डालने का सबसे अच्छा समाधान होगा, ताकि हम एलिमेंट पर क्लिक करने पर क्लाइंटएक्स और क्लाइंट के साथ वास्तविक निर्देशांक प्राप्त कर सकें।
बपतिस्मा

1
तो, @Adam और meouw, क्या आप कह रहे हैं कि पहला कोड ब्लॉक गलत है? फिर उसे पूरी तरह से क्यों नहीं हटाया गया? (यह सवाल पिछले कुछ वर्षों में काफी दर्शकों ने देखा है, अगर वे गलत हैं तो उन्हें दूर करना अच्छा हो सकता है?)
अर्जन

2
@baptx: मुझे पता है कि यह देर से जवाब है, लेकिन मैंने आपकी टिप्पणी को जल्द नहीं देखा। अधिक वैकल्पिक मानकों के विकल्प के लिए मेरा जवाब नीचे देखें - आपको वास्तव में फ़ालबैक कोड की आवश्यकता नहीं है, क्योंकि ब्राउज़र ने लंबे समय तक इसका समर्थन किया है।
एंडी ई

242

इसने मेरे लिए काम किया (उच्चतम मतदान उत्तर से संशोधित):

function getOffset(el) {
  const rect = el.getBoundingClientRect();
  return {
    left: rect.left + window.scrollX,
    top: rect.top + window.scrollY
  };
}

इसके उपयोग से हम कॉल कर सकते हैं

getOffset(element).left

या

getOffset(element).top

1
जब तत्व को divसीएसएस का उपयोग करके केंद्रित किया जाता है तो केवल मेरे लिए यह समाधान काम करता है top:50%, left:50%; transform:translate(-50%, -50%);... उत्कृष्ट। सफ़ेद सहमत @ScottBiggs सवाल। सादगी के लिए तार्किक की तलाश है।
नीलकंठ

3
शायद इसका विजेता एंडी ई के समाधान के समान नहीं है, लेकिन पुराने ब्राउज़रों में काम नहीं करता है <IE9
niltoid

getBoundingClientRect मेरे प्रदर्शन चार्ट में बड़े पैमाने पर दमनकारी स्पाइक का कारण बनता है
फ्रुम्बर्ट

1
आप परिभाषित करना चाहिए rectका उपयोग कर var, letया const। अन्यथा, इसे परिभाषित किया गया है window.rect
hev1

2
left: rect.left + window.scrollX + (rect.width / 2), top: rect.top + window.scrollY + (rect.height / 2)किसी तत्व की मध्य स्थिति
लौटाएगा

95

यदि आप चाहते हैं कि यह केवल जावास्क्रिप्ट में किया जाए , तो यहां कुछ एक लाइनर्स का उपयोग किया जा रहा हैgetBoundingClientRect()

window.scrollY + document.querySelector('#elementId').getBoundingClientRect().top // Y

window.scrollX + document.querySelector('#elementId').getBoundingClientRect().left // X

पहली पंक्ति offsetTopदस्तावेज़ के सापेक्ष Y कहेगी। दूसरी पंक्ति offsetLeftदस्तावेज़ के सापेक्ष X कहेगी।

getBoundingClientRect() एक जावास्क्रिप्ट फ़ंक्शन है जो विंडो के व्यूपोर्ट के सापेक्ष तत्व की स्थिति देता है।


2
इसका समाधान होना चाहिए। यहां कोई लंबा कोड bs नहीं है, इसकी समझ और इसकी बहुत सटीक है!
ई एलेक्सिस एमटी

2
क्या होगा यदि तत्व एक स्क्रॉल करने योग्य तत्व के भीतर है? इसे करने का एकमात्र तरीका सभी मूल तत्वों का ऑफसेट-समिट करना है, जैसे अन्य उत्तर सुझाते हैं
दिमित्री पिसारेव

जैसा कि दिमित्री कहता है, यह गलत और बहुत त्रुटिपूर्ण है। उसके पास उतने वोट नहीं होने चाहिए जितने कि वो हैं। यह हमेशा एक स्क्रॉल करने योग्य तत्व में होगा क्योंकि दस्तावेज़ स्वयं स्क्रॉल किया जा सकता है। दूसरे शब्दों में, जब तक कि संपूर्ण दस्तावेज़ व्यूपोर्ट में फिट नहीं होता है, यह हमेशा गलत होगा यदि उपयोगकर्ता ने मुख्य विंडो को बिल्कुल भी स्क्रॉल किया है।
लेव

46

अधिकांश ब्राउज़रों पर HTML तत्व होंगे: -

offsetLeft
offsetTop

ये तत्व की स्थिति को उसके निकटतम माता-पिता के सापेक्ष निर्दिष्ट करते हैं जिसमें लेआउट है। इस अभिभावक को अक्सर ऑफ़सेट प्रॉपर्टी पर bif एक्सेस किया जा सकता है।

IE और FF3 है

clientLeft
clientTop

ये गुण कम आम हैं, वे अपने माता-पिता ग्राहक क्षेत्र के साथ एक तत्व स्थिति निर्दिष्ट करते हैं (गद्देदार क्षेत्र ग्राहक क्षेत्र का हिस्सा है लेकिन सीमा और मार्जिन नहीं है)।


36

यदि पृष्ठ में शामिल है - कम से कम- किसी भी "DIV", meouw द्वारा दिए गए फ़ंक्शन वर्तमान पृष्ठ सीमाओं से परे "Y" मान को फेंकता है। सटीक स्थिति खोजने के लिए, आपको ऑफसेटप्रेंट और पेरेंटनोड दोनों को संभालने की आवश्यकता है।

नीचे दिए गए कोड की कोशिश करें (यह FF2 के लिए जाँच की गई है):


var getAbsPosition = function(el){
    var el2 = el;
    var curtop = 0;
    var curleft = 0;
    if (document.getElementById || document.all) {
        do  {
            curleft += el.offsetLeft-el.scrollLeft;
            curtop += el.offsetTop-el.scrollTop;
            el = el.offsetParent;
            el2 = el2.parentNode;
            while (el2 != el) {
                curleft -= el2.scrollLeft;
                curtop -= el2.scrollTop;
                el2 = el2.parentNode;
            }
        } while (el.offsetParent);

    } else if (document.layers) {
        curtop += el.y;
        curleft += el.x;
    }
    return [curtop, curleft];
};

1
एफएफ 24.4 के साथ अन्य समाधानों के साथ भी उपरोक्त कोड काम नहीं करता है जब बॉर्डर की चौड़ाई पोजिशनिंग लेआउट के हिस्से के रूप में मौजूद होती है।
लूटने

तुम एक जीवन रक्षक हो। मैं अभी कुछ बहुत गहरे GWT बग्स के माध्यम से काम कर रहा हूँ और इसे एक JSNI विधि में फेंकना मेरी सभी समस्याओं को हल करता है !!
को 'बायरन'

35

आप Element.prototypeकिसी भी तत्व के शीर्ष / बाएँ पाने के लिए दो गुण जोड़ सकते हैं ।

Object.defineProperty( Element.prototype, 'documentOffsetTop', {
    get: function () { 
        return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
    }
} );

Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
    get: function () { 
        return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
    }
} );

इसे इस तरह कहा जाता है:

var x = document.getElementById( 'myDiv' ).documentOffsetLeft;

यहां परिणामों को jQuery offset().topऔर .left: http://jsfiddle.net/ThinkingStiff/3G7EZ/ से तुलना करते हुए एक डेमो दिया गया है


14
संशोधन Element.prototypeको आमतौर पर एक बुरा विचार माना जाता है । यह कोड को बनाए रखने के लिए वास्तव में कठिन होता है। इसके अलावा, यह कोड स्क्रॉल करने के लिए जिम्मेदार नहीं है।
जारेड फोर्सिथ

23

पृष्ठ के सापेक्ष स्थिति को कुशलता से प्राप्त करने के लिए, और पुनरावर्ती फ़ंक्शन का उपयोग किए बिना: (IE भी शामिल है)

var element = document.getElementById('elementId'); //replace elementId with your element's Id.
var rect = element.getBoundingClientRect();
var elementLeft,elementTop; //x and y
var scrollTop = document.documentElement.scrollTop?
                document.documentElement.scrollTop:document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft?                   
                 document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;

सभी महत्वपूर्ण स्क्रॉलटॉप / स्क्रॉललैट शामिल करने से यह उत्तर थोड़ा और सही हो जाता है।
scunliffe

19

इस तरह से कुछ के बारे में कैसे, तत्व की आईडी पास करके और यह बाईं या शीर्ष पर वापस आ जाएगी, हम उन्हें भी जोड़ सकते हैं:

1) बाईं ओर खोजें

function findLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.left + window.scrollX;
} //call it like findLeft('#header');

2) शीर्ष खोजें

function findTop(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.top + window.scrollY;
} //call it like findTop('#header');

या 3) बाएँ और शीर्ष को एक साथ खोजें

function findTopLeft(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return {top: rec.top + window.scrollY, left: rec.left + window.scrollX};
} //call it like findTopLeft('#header');

16

एक जावास्क्रिप्ट-फ्रेमवर्क का उपयोग करके आपको बेहतर सेवा दी जा सकती है, जिसमें ब्राउज़र-इंडिपेंडेंट फैशन में ऐसी जानकारी (और बहुत अधिक!) वापस करने के लिए फ़ंक्शन हैं। यहाँ कुछ है:

इन चौखटे के साथ, आप कुछ ऐसा कर सकते हैं: $('id-of-img').top छवि का y- पिक्सेल समन्वय प्राप्त करने के लिए।


2
@ कोस्टा वे सभी प्रकार के फ़ंक्शंस का उपयोग करते हैं, हालांकि यह एक विकसित क्षेत्र है, क्योंकि विभिन्न ब्राउज़र विनिर्देश के अनुसार अलग-अलग होते हैं। इतना कोड "फिक्सिंग" चीजों से संबंधित है जो गलत हो जाता है। आपको वास्तव में स्रोत कोड को देखना चाहिए।
शालोम क्रेमर

18
@scraimer: jQuery और YUI फ्रेमवर्क नहीं हैं !!! ये पुस्तकालय हैं ! यह वैसा नहीं है। Jquery.com का हवाला देते हुए : "jQuery एक तेज़, छोटा और सुविधा संपन्न जावास्क्रिप्ट लाइब्रेरी है ।" यूटिलिट्स.कॉम का हवाला देते हुए (आप URL में "जादू" शब्द भी देख सकते हैं ...): "YUI एक नि
Sk8erPeter

29
तो आपको इस सरल कार्य के लिए विशाल पुस्तकालयों का उपयोग करना चाहिए? आवश्यक नहीं। मुझे नफरत है कि हर बार जब मैं js के साथ कुछ करना चाहता हूं, मुझे ये jQuery समाधान मिलते हैं। jQuery जेएस नहीं है!
ओप्टैट जॉबर

1
@OpptattJobber मैं सहमत हूँ ... JQuery जावास्क्रिप्ट नहीं है। यह जावास्क्रिप्ट पर निर्भर करता है लेकिन इसकी एक अलग प्रोग्रामिंग भाषा है।
निक मैनिंग

5
@NickManning यह एक नई भाषा नहीं है, डोम के लिए इसकी एक अमूर्त परत है जो आपके कोड में सीधे संगतता और प्रदर्शन वर्कराउंड लिखने के लिए समाप्त कर देती है। यदि आप jQuery का उपयोग नहीं करते हैं, तो आपको किसी भी प्रकार के एब्स्ट्रक्शन लेयर का उपयोग करना चाहिए।
गिन्मैन

15

jQuery .offset () पहले तत्व के वर्तमान निर्देशांक प्राप्त करेगा, या दस्तावेज़ के सापेक्ष मिलान तत्वों के सेट में हर तत्व के निर्देशांक सेट करेगा।


किसी कारण से यह अन्य ब्राउज़रों की तुलना में IE में समान परिणाम नहीं दे रहा है। मुझे लगता है कि IE में यह खिड़की के सापेक्ष स्थिति दे रहा है, इसलिए यदि आप स्क्रॉल करते हैं, तो आपको IE में दूसरों की तुलना में अलग-अलग परिणाम प्राप्त होंगे
अब्दुल रहीम हदद

1
ऑफसेट () ज़ूम से भ्रमित होता है, कम से कम एंड्रॉइड क्रोम में, इसलिए यह बेकार है। stackoverflow.com/a/11396681/1691517 ज़ूम-सहन करने का तरीका दिखाता है।
टिमो किखोनेन

10

मैंने @ meww का उत्तर ले लिया है, क्लाइंटलाइफ़ में जोड़ा गया है जो सीमा के लिए अनुमति देता है, और फिर तीन संस्करण बनाए:

getAbsoluteOffsetFromBody - @ meouw के समान, यह शरीर या दस्तावेज़ के HTML तत्व (quirks मोड के आधार पर) के सापेक्ष पूर्ण स्थिति प्राप्त करता है

getAbsoluteOffsetFromGivenElement - दिए गए तत्व (सापेक्ष) के सापेक्ष पूर्ण स्थिति देता है। ध्यान दें कि दिए गए तत्व में तत्व एल होना चाहिए, या यह getAbsoluteOffsetFromBody के समान व्यवहार करेगा। यह उपयोगी है यदि आपके पास दो तत्व हैं जो किसी अन्य (ज्ञात) तत्व के भीतर निहित हैं (वैकल्पिक रूप से नोड पेड़ को कई नोड्स) और उन्हें एक ही स्थिति बनाना चाहते हैं।

getAbsoluteOffsetFromRelative - स्थिति के साथ पहले मूल तत्व के सापेक्ष पूर्ण स्थिति देता है: सापेक्ष। यह एक ही कारण के लिए getAbsoluteOffsetFromGivenElement के समान है, लेकिन केवल पहले मिलान तत्व के रूप में ही जाएगा।

getAbsoluteOffsetFromBody = function( el )
{   // finds the offset of el from the body or html element
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromGivenElement = function( el, relativeEl )
{   // finds the offset of el from relativeEl
    var _x = 0;
    var _y = 0;
    while( el && el != relativeEl && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

getAbsoluteOffsetFromRelative = function( el )
{   // finds the offset of el from the first parent with position: relative
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
    {
        _x += el.offsetLeft - el.scrollLeft + el.clientLeft;
        _y += el.offsetTop - el.scrollTop + el.clientTop;
        el = el.offsetParent;
        if (el != null)
        {
            if (getComputedStyle !== 'undefined')
                valString = getComputedStyle(el, null).getPropertyValue('position');
            else
                valString = el.currentStyle['position'];
            if (valString === "relative")
                el = null;
        }
    }
    return { top: _y, left: _x };
}

यदि आपको अभी भी समस्या हो रही है, विशेष रूप से स्क्रॉलिंग से संबंधित है, तो आप http://www.greywyvern.com/?post=331 को देखने का प्रयास कर सकते हैं - मैंने गेट्सल में कम से कम एक संदिग्ध कोड का ध्यान दिया, जो ठीक-ठाक ब्राउज़र होना चाहिए। , लेकिन बाकी का परीक्षण नहीं किया है।


दिलचस्प ... लेकिन एज getAbsoluteOffsetFromBody (तत्व) पर .top मैं स्क्रॉल के रूप में एक अलग मान देता है, क्रोम में मैं स्क्रॉल के रूप में सुसंगत रहता है। ऐसा लगता है कि एज स्क्रॉल स्थिति के साथ समायोजित हो रहा है। जब तत्व को स्क्रॉल किया जाता है तो मुझे एक नकारात्मक मूल्य मिलता है।
नॉर्मन

getAbsoluteOffsetFromRelative ने मेरा दिन बना दिया, मुझे बूटस्ट्रैप के जावास्क्रिप्ट के बिना बूटस्ट्रैप टूलटिप को फिर से तैयार करना पड़ा, इससे मुझे बहुत मदद मिली।
15

बस अगर मेव ने अपना उपयोगकर्ता नाम बदल दिया है, तो उत्तर देने के लिए लिंक: stackoverflow.com/a/442474/3654837 । (मैं इस पुराने धागे को इतना नहीं
उछालना

8

अगर jQuery का उपयोग कर, आयाम प्लगइन उत्कृष्ट है और आपको वही निर्दिष्ट करने की अनुमति देता है जो आप चाहते हैं।

जैसे

पैडिंग के साथ रिलेटिव पोजिशन, पोजिशन, पोजिशन के बिना एब्सोल्यूट पोजिशन ...

यह चल रहा है, चलो बस कहते हैं कि बहुत कुछ है जो आप इसके साथ कर सकते हैं।

इसके अलावा jQuery का उपयोग करने का बोनस यह हल्का फ़ाइल आकार और आसान उपयोग है, आप इसके बिना जावास्क्रिप्ट पर वापस नहीं जाएंगे।


8

यह सबसे अच्छा कोड है जिसे मैंने बनाने में कामयाब रहा है (jrf के ऑफ़सेट () के विपरीत, iframes में भी काम करता है)। लगता है webkit का व्यवहार कुछ अलग है।

Meouw की टिप्पणी के आधार पर:

function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft - el.scrollLeft;
        _y += el.offsetTop - el.scrollTop;
        // chrome/safari
        if ($.browser.webkit) {
            el = el.parentNode;
        } else {
            // firefox/IE
            el = el.offsetParent;
        }
    }
    return { top: _y, left: _x };
}

ध्यान दें कि आपको jQueryउपयोग करने की आवश्यकता होगी $.browser.webkit; आपको navigator.userAgentशुद्ध के साथ ऐसा ही करने की आवश्यकता होगी JavaScript
एसपी

2
$ .browser अब jQuery के नवीनतम संस्करण
Gus

दुर्भाग्य से एफएफ 24.4 के साथ भी उपरोक्त कोड तब काम नहीं करता है जब बॉर्डर की चौड़ाई पोजिशनिंग लेआउट के हिस्से के रूप में मौजूद हो।
लूटने

8

यदि आप jQuery का उपयोग कर रहे हैं, तो यह एक सरल उपाय हो सकता है:

<script>
  var el = $("#element");
  var position = el.position();
  console.log( "left: " + position.left + ", top: " + position.top );
</script>

8

छोटे और छोटे के बीच अंतर

function getPosition( el ) {
    var x = 0;
    var y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
    x += el.offsetLeft - el.scrollLeft;
    y += el.offsetTop - el.scrollTop;
    el = el.offsetParent;
    }
    return { top: y, left: x };
}

एक उदाहरण निर्देशांक देखें: http://javascript.info/tutorial/coordinates


यह दुर्भाग्य से सभी तत्वों के लिए काम नहीं करता है जो एक आधुनिक HTML दस्तावेज़ के अंदर मिल सकता है। एंबेडेड <svg>तत्वों, उदाहरण के लिए, की जरूरत नहीं है offsetLeft, offsetTopऔर offsetParentगुण।
जोनाथन यूनिस

इसकी बस DIVया IMGनहीं SVG। देखें "एक उदाहरण देखें निर्देशांक"? आप पा सकते हैं वस्तु svg स्थिति कॉल getOffsetRect है , कोशिश करें और ऑब्जेक्ट काम पर निर्भर करें।
किंग्डराइड

7

मेरे द्वारा पाया गया सबसे साफ तरीका jQuery के द्वारा इस्तेमाल की जाने वाली तकनीक का एक सरलीकृत संस्करण है offset। कुछ अन्य उत्तरों के साथ भी ऐसा ही शुरू होता है getBoundingClientRect; यह तब स्क्रॉल स्थिति के साथ-साथ (अक्सर डिफ़ॉल्ट) जैसी मार्जिन windowके documentElementलिए समायोजित करने के लिए और का उपयोग करता है body

var rect = el.getBoundingClientRect();
var docEl = document.documentElement;

var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;


6

हालांकि यह बहुत सारे उत्तरों के तल पर खो जाने की संभावना है, यहां शीर्ष समाधान मेरे लिए काम नहीं कर रहे थे।
जहां तक ​​मैं बता सकता था कि न तो किसी अन्य उत्तर ने मदद की है।

स्थिति :
एक HTML5 पृष्ठ में मेरे पास एक मेनू था जो हेडर के अंदर एक नव तत्व था (हेडर नहीं है लेकिन किसी अन्य तत्व में हेडर है)।
मैं चाहता था कि उपयोगकर्ता द्वारा स्क्रॉल किए जाने के बाद नेविगेशन शीर्ष पर रहे, लेकिन इससे पहले हेडर निरपेक्ष स्थिति में था (इसलिए मैं इसे थोड़ा और ओवरले कर सकता था)।
ऊपर दिए गए समाधानों में कभी परिवर्तन नहीं हुआ क्योंकि .offsetTop बदलने नहीं जा रहा था क्योंकि यह एक निरपेक्ष तैनात तत्व था। इसके अतिरिक्त .scrollTop संपत्ति केवल सबसे ऊपरी तत्व का शीर्ष था ... जो कि 0 कहना है और हमेशा 0 होगा।
किसी भी परीक्षण को मैंने इन दोनों का उपयोग करके किया (और getBoundingClientRect परिणामों के साथ भी ऐसा ही) मुझे यह नहीं बताएगा कि क्या नेविगेशन बार के शीर्ष ने कभी देखने योग्य पृष्ठ के शीर्ष पर स्क्रॉल किया (फिर से, जैसा कि कंसोल में बताया गया है, वे स्क्रॉल करते समय बस एक ही संख्या में रहे हुआ)।

समाधान
मेरे लिए समाधान का उपयोग कर रहा था

window.visualViewport.pageTop

पेजटॉप प्रॉपर्टी का मूल्य स्क्रीन के देखने योग्य अनुभाग को दर्शाता है, इसलिए मुझे ट्रैक करने की अनुमति देता है जहां एक तत्व देखने योग्य क्षेत्र की सीमाओं के संदर्भ में है।

शायद कहने के लिए अनावश्यक, कभी भी मैं स्क्रॉलिंग से निपट रहा हूं मैं इस समाधान का उपयोग करने की उम्मीद करता हूं, जो कि स्क्रॉल किए जाने वाले तत्वों के आंदोलन का जवाब देता है।
आशा है कि यह किसी और की मदद करता है।
महत्वपूर्ण नोट: यह वर्तमान में क्रोम और ओपेरा में काम करने के लिए प्रतीत होता है और निश्चित रूप से फ़ायरफ़ॉक्स (6-2018) में नहीं होता है ... जब तक फ़ायरफ़ॉक्स विज़ुअल व्यूपोर्ट का समर्थन करता है मैं इस पद्धति का उपयोग नहीं करने की सलाह देता हूं, (और मुझे आशा है कि वे जल्द ही करते हैं ... यह बहुत कुछ बनाता है बाकी से ज्यादा समझदारी)।


अद्यतन:
बस इस समाधान के बारे में एक नोट।
जबकि मुझे अभी भी पता है कि मैंने उन स्थितियों के लिए बहुत मूल्यवान साबित किया है जिनमें "... प्रोग्रामिक रूप से स्क्रॉल किए जा रहे तत्वों के आंदोलन का जवाब है।" उपयुक्त है। मेरे पास समस्या के लिए बेहतर समाधान सीएसएस का उपयोग स्थिति निर्धारित करने के लिए था : चिपचिपातत्व पर। चिपचिपे का उपयोग करना आप जावास्क्रिप्ट का उपयोग किए बिना एक तत्व शीर्ष पर रह सकते हैं (नोट: ऐसे समय होते हैं जो तय किए गए तत्व को बदलने के रूप में प्रभावी रूप से काम नहीं करेंगे लेकिन अधिकांश उपयोगों के लिए चिपचिपा दृष्टिकोण बेहतर होने की संभावना होगी)

UPDATE01:
तो यह एहसास हुआ कि एक अलग पृष्ठ के लिए मेरे पास एक आवश्यकता थी जहां मुझे हल्के जटिल स्क्रॉलिंग सेटअप में एक तत्व की स्थिति का पता लगाने की आवश्यकता थी (एक संदेश के भाग के रूप में पिछले स्क्रॉल करने वाले लंबन प्लस तत्व)। मुझे उस परिदृश्य में एहसास हुआ कि कुछ प्रदान करने के लिए निम्नलिखित ने मुझे जो मूल्य निर्धारित किया था, वह प्रदान किया:

  let bodyElement = document.getElementsByTagName('body')[0];
  let elementToTrack = bodyElement.querySelector('.trackme');
  trackedObjPos = elementToTrack.getBoundingClientRect().top;
  if(trackedObjPos > 264)
  {
    bodyElement.style.cssText = '';
  }

आशा है कि यह उत्तर अब और अधिक व्यापक रूप से उपयोगी है।


जब आप जवाबों को छाँटने के लिए सक्रिय क्लिक करते हैं तो यह बहुत सारे उत्तरों में सबसे ऊपर होने की संभावना है
lucchi

@lucchi: D अच्छी तरह से मुझे लगता है कि मैं शीर्ष @ पाठ को हटा सकता हूं ... हालांकि मैं सिर्फ इस एक पर फिर से हुआ और मुझे एहसास हुआ कि मुझे अपनी समस्या का बेहतर समाधान मिल गया है ... हालांकि मेरा उत्तर अधिक है अधिक पूर्ण उत्तरों पर ध्यान दें। मुझे संदेह है कि मेरी आवश्यकताएं शायद इतनी सामान्य नहीं थीं कि अन्य उत्तर मेरे काम नहीं आते?
MER

1
मैं वैसे भी आपके उत्तर की सराहना करता हूं, यह आपको केवल यह बताने के लिए था कि, कोई भी इच्छुक व्यक्ति इस बात से अवगत होगा कि आपने कुछ नया लिखा है। आप अकेले नहीं हैं ....
लुच्ची

5

मैंने इसे इस तरह किया था इसलिए यह पुराने ब्राउज़रों के साथ क्रॉस-संगत था।

// For really old browser's or incompatible ones
    function getOffsetSum(elem) {
        var top = 0,
            left = 0,
            bottom = 0,
            right = 0

         var width = elem.offsetWidth;
         var height = elem.offsetHeight;

        while (elem) {
            top += elem.offsetTop;
            left += elem.offsetLeft;
            elem = elem.offsetParent;
        }

         right = left + width;
         bottom = top + height;

        return {
            top: top,
            left: left,
            bottom: bottom,
            right: right,
        }
    }

    function getOffsetRect(elem) {
        var box = elem.getBoundingClientRect();

        var body = document.body;
        var docElem = document.documentElement;

        var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
        var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;

        var clientTop = docElem.clientTop;
        var clientLeft = docElem.clientLeft;


        var top = box.top + scrollTop - clientTop;
        var left = box.left + scrollLeft - clientLeft;
        var bottom = top + (box.bottom - box.top);
        var right = left + (box.right - box.left);

        return {
            top: Math.round(top),
            left: Math.round(left),
            bottom: Math.round(bottom),
            right: Math.round(right),
        }
    }

    function getOffset(elem) {
        if (elem) {
            if (elem.getBoundingClientRect) {
                return getOffsetRect(elem);
            } else { // old browser
                return getOffsetSum(elem);
            }
        } else
            return null;
    }

यहाँ जावास्क्रिप्ट में निर्देशांक के बारे में अधिक जानकारी: http://javascript.info/tutorial/coordinates


4

किसी तत्व की कुल ऑफ़सेट प्राप्त करने के लिए, आप सभी अभिभावकों से पुन: राशि प्राप्त कर सकते हैं:

function getParentOffsets(el): number {
if (el.offsetParent) {
    return el.offsetParent.offsetTop + getParentOffset(el.offsetParent);
} else {
    return 0;
}
}

इस उपयोगिता फ़ंक्शन के साथ एक डोम तत्व की कुल शीर्ष ऑफसेट है:

el.offsetTop + getParentOffsets(el);

3
/**
 *
 * @param {HTMLElement} el
 * @return {{top: number, left: number}}
 */
function getDocumentOffsetPosition(el) {
    var position = {
        top: el.offsetTop,
        left: el.offsetLeft
    };
    if (el.offsetParent) {
        var parentPosition = getDocumentOffsetPosition(el.offsetParent);
        position.top += parentPosition.top;
        position.left += parentPosition.left;
    }
    return position;
}

उत्तर के लिए थिंकिंगस्टिफ का धन्यवाद , यह इसका केवल एक और संस्करण है।


2

मैंने सफलतापूर्वक एंडी ई के समाधान का उपयोग बूटस्ट्रैप 2 मोडल की स्थिति के लिए किया है, जिस पर उपयोगकर्ता द्वारा क्लिक की जाने वाली तालिका पंक्ति में क्या लिंक है। पृष्ठ एक टेपेस्ट्री 5 पृष्ठ है और नीचे जावा जावास्क्रिप्ट कक्षा पृष्ठ में आयात किया गया है।

जावास्क्रिप्ट:

function setLinkPosition(clientId){
var bodyRect = document.body.getBoundingClientRect(),
elemRect = clientId.getBoundingClientRect(),
offset   = elemRect.top - bodyRect.top;
offset   = offset + 20;
$('#serviceLineModal').css("top", offset);

}

मेरा मोडल कोड:

<div id="serviceLineModal" class="modal hide fade add-absolute-position" data-backdrop="static" 
 tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="top:50%;">
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
    <h3 id="myModalLabel">Modal header</h3>
</div>

<div class="modal-body">
    <t:zone t:id="modalZone" id="modalZone">
        <p>You selected service line number: ${serviceLineNumberSelected}</p>
    </t:zone>
</div>

<div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <!-- <button class="btn btn-primary">Save changes</button> -->
</div>

लूप में लिंक:

<t:loop source="servicesToDisplay" value="service" encoder="encoder">
<tr style="border-right: 1px solid black;">       
    <td style="white-space:nowrap;" class="add-padding-left-and-right no-border"> 
        <a t:type="eventLink" t:event="serviceLineNumberSelected" t:context="service.serviceLineNumber" 
            t:zone="pageZone" t:clientId="modalLink${service.serviceLineNumber}"
            onmouseover="setLinkPosition(this);">
            <i class="icon-chevron-down"></i> <!-- ${service.serviceLineNumber} -->
        </a>
    </td>

और पेज क्लास में जावा कोड:

void onServiceLineNumberSelected(String number){
    checkForNullSession();
    serviceLineNumberSelected = number;
    addOpenServiceLineDialogCommand();
    ajaxResponseRenderer.addRender(modalZone);
}

protected void addOpenServiceLineDialogCommand() {
    ajaxResponseRenderer.addCallback(new JavaScriptCallback() {
        @Override
        public void run(JavaScriptSupport javascriptSupport) {
            javascriptSupport.addScript("$('#serviceLineModal').modal('show');");
        }
    });
}

आशा है कि यह किसी की मदद करता है, इस पोस्ट ने मदद की।


इस js कोड ने मेरी मदद की, मेरे पास कई प्लेसहोल्डर्स .aspx पृष्ठों का उपयोग करके एक पुराना वेबफॉर्म ऐप है और मैं यह पता नहीं लगा सका कि एक पॉपअप बॉक्स के appendChild () में कैसे मैं इसे व्यूपोर्ट में लाने के लिए बना रहा था क्योंकि संपूर्ण DOM का पेड़ अजीब है कई प्लेसहोल्डर्स और गलत मार्कअप के साथ। Body.getBoundingClientRect () का उपयोग करना तब स्थिति में अपने शीर्ष का उपयोग करना जो मुझे चाहिए था। धन्यवाद।
ब्रैड मार्टिन

1

बहुत शोध और परीक्षण के बाद यह काम करने लगता है

function getPosition(e) {
    var isNotFirefox = (navigator.userAgent.toLowerCase().indexOf('firefox') == -1);
    var x = 0, y = 0;
    while (e) {
        x += e.offsetLeft - e.scrollLeft + (isNotFirefox ? e.clientLeft : 0);
        y += e.offsetTop - e.scrollTop + (isNotFirefox ? e.clientTop : 0);
        e = e.offsetParent;
    }
    return { x: x + window.scrollX, y: y + window.scrollY };
}

http://jsbin.com/xuvovalifo/edit?html,js,output देखें


1

बस मैंने सोचा कि मैं इसे भी वहीं फेंक दूंगा।
मैं पुराने ब्राउज़रों में इसका परीक्षण नहीं कर पाया, लेकिन यह शीर्ष 3. के नवीनतम में काम करता है। :)

Element.prototype.getOffsetTop = function() {
    return ( this.parentElement )? this.offsetTop + this.parentElement.getOffsetTop(): this.offsetTop;
};
Element.prototype.getOffsetLeft = function() {
    return ( this.parentElement )? this.offsetLeft + this.parentElement.getOffsetLeft(): this.offsetLeft;
};
Element.prototype.getOffset = function() {
    return {'left':this.getOffsetLeft(),'top':this.getOffsetTop()};
};

0

चूंकि अलग-अलग ब्राउज़र सीमा, पैडिंग, मार्जिन और आदि को अलग-अलग तरीके से प्रस्तुत कर रहे हैं। मैंने प्रत्येक रूट तत्व में विशिष्ट तत्व के शीर्ष और बाएं पदों को पुनः प्राप्त करने के लिए एक छोटा सा कार्य लिखा, जिसे आप सटीक आयाम में चाहते हैं:

function getTop(root, offset) {
    var rootRect = root.getBoundingClientRect();
    var offsetRect = offset.getBoundingClientRect();
    return offsetRect.top - rootRect.top;
}

बाईं स्थिति को प्राप्त करने के लिए आपको वापस लौटना होगा:

    return offsetRect.left - rootRect.left;

-1

बाएं और शीर्ष के संबंध में तलाक की स्थिति प्राप्त करें

  var elm = $('#div_id');  //get the div
  var posY_top = elm.offset().top;  //get the position from top
  var posX_left = elm.offset().left; //get the position from left 

मैंने वोट दिया क्योंकि नीचे और दाएं ऑफसेट के गुण नहीं हैं ()
मैक्रोमैन

@ मैक्रोमैन, मैं आपके निर्णय का सम्मान करता हूं लेकिन मैंने पहले ही पाठ में समझाया है कि "नीचे और दाएं कोड का परीक्षण नहीं किया गया है।" इसके अलावा, मैं बहुत जल्द अपना कोड अपडेट करूंगा।
विशाल

मुझे लगता है कि el.offsetTopऔर el.offsetLeft(ओ पी jQuery के बारे में कुछ नहीं कहा ... मुझे यकीन है कि क्यों अपने जवाब jQuery या तो ... का उपयोग करता है नहीं कर रहा हूँ)
mesqueeb
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.