एक मूल कंटेनर के सापेक्ष तत्व की स्थिति / ऑफसेट प्राप्त करें?


125

मुझे jQuery के साथ काम करने की आदत है। हालांकि मेरे वर्तमान प्रोजेक्ट में मैं zepto.js का उपयोग करता हूं। Zepto position()jQuery की तरह एक विधि प्रदान नहीं करता है। Zepto केवल साथ आता है offset()

किसी भी विचार कैसे मैं शुद्ध js के साथ या Zepto के साथ एक माता पिता के सापेक्ष एक कंटेनर की भरपाई कर सकते हैं?


4
जावास्क्रिप्ट सवाल पूछने पर डाउन-वोटिंग एक jQuery के उत्तर (जिसे jQuery के रूप में भी लेबल नहीं किया गया है) स्वीकार नहीं किया गया है।
जॉन

@ जॉन ने आपको जिप्टो टैग नोटिस किया?
सुपरशरप

JavaScriptजब आप शुद्ध जावास्क्रिप्ट का उपयोग कर रहे हों तो @Supersharp टैग का उपयोग करें । यदि आप किसी फ्रेमवर्क या लाइब्रेरी का उपयोग कर रहे हैं तो आप टैग का उपयोग नहीं करते हैं JavaScript। अगर आपका नाम जेफ है तो मैं आपको सैली नहीं कहूंगा।
जॉन

@ यह एक राय है, लेकिन ऐसा नहीं है कि एसओ कैसे काम करता है। कृपया जावास्क्रिप्ट टैग गाइड पढ़ें। इस मामले में इसका उपयोग लाइब्रेरी टैग के साथ किया जाना चाहिए।
सुपरस्पर्श

@Supersharp हाँ एसओ उस तरह अक्षम है; शाब्दिक टैग मुद्रास्फीति। 😒︎
जॉन

जवाबों:


188

चेतावनी: jQuery, मानक जावास्क्रिप्ट नहीं

element.offsetLeftऔर element.offsetTopइसके संबंध में एक तत्व की स्थिति खोजने के लिए शुद्ध जावास्क्रिप्ट गुण हैं offsetParent; relativeया की स्थिति के साथ निकटतम मूल तत्व होने के नातेabsolute

वैकल्पिक रूप से, आप हमेशा एक तत्व और उसके माता-पिता की स्थिति प्राप्त करने के लिए Zepto का उपयोग कर सकते हैं , और बस दो को घटा सकते हैं:

var childPos = obj.offset();
var parentPos = obj.parent().offset();
var childOffset = {
    top: childPos.top - parentPos.top,
    left: childPos.left - parentPos.left
}

इसका लाभ आपको अपने माता-पिता के सापेक्ष एक बच्चे की भरपाई देने में है, भले ही वह माता-पिता के पद पर न हो।


9
एलिमेंट की स्थिति staticमाता-पिता की भरपाई नहीं है।
एस्लेइजा


1
स्थिति के बारे में क्या तय हुआ? क्या वे माता-पिता की भरपाई करते हैं?
अय्याश

1
हां, @ अय्या- स्थिति भी एक नया ऑफसेट संदर्भ बनाता है
mmmeff

9
@vsync jQuery जनवरी 2016 में E9 तक पहुंचने के बाद से किसी भी चीज़ का राजा नहीं है, हमारे पास सभी प्रमुख ब्राउज़रों में एक मानकीकृत DOM चयन है, शुद्ध js सीखें। एसओ पर किसी भी स्थान का उपयोग करने के लिए क्या रूपरेखा है, इसके बारे में भी राय है, क्योंकि यह परियोजना और लक्ष्य मंच पर बहुत अधिक निर्भर करता है।
हंस कोच

72

शुद्ध जेएस में सिर्फ उपयोग offsetLeftऔर offsetTopगुण हैं।
उदाहरण फिडल: http://jsfiddle.net/WKZ8P/

var elm = document.querySelector('span');
console.log(elm.offsetLeft, elm.offsetTop);
p   { position:relative; left:10px; top:85px; border:1px solid blue; }
span{ position:relative; left:30px; top:35px; border:1px solid red; }
<p>
    <span>paragraph</span>
</p>


धन्यवाद। क्या पैरेंट.पैरेंट एलिमेंट को ऑफसेट करने का कोई तरीका है?
मैट

2
p.offsetTop + p.parentNode.offsetTopआप इसे पुनरावर्ती फ़ंक्शन कॉल में लपेट सकते हैं जैसे कि PPK ने कुछ साल पहले प्रस्तावित किया था। आप फ़ंक्शन को बदल सकते हैं या तो ऊपर जाने के लिए स्तरों की संख्या को पास कर सकते हैं या एक चयनकर्ता का नकल करने के लिए उपयोग कर सकते हैं $(selector).parents(parentSelector)। मैं इस समाधान को प्राथमिकता दूंगा क्योंकि जिप्टो कार्यान्वयन केवल समर्थन करने वाले ब्राउज़रों पर काम करता है getBoundingClientsRect- जो कुछ मोबाइल नहीं करते हैं।
टॉरस्टेन वाल्टर

मुझे लगा getBoundingClientsRectकि व्यापक रूप से समर्थित है ... अगर किसी को पता है कि कौन से मोबाइल इसका समर्थन नहीं करते हैं तो मुझे दिलचस्पी होगी (इसके बारे में मोबाइलों के लिए कोई समर्थन तालिका नहीं मिल सकती है)।
नोबिता

यह शायद सबसे सही उत्तर है, हालांकि यह चिह्नित नहीं है। मेरा व्यक्तिगत समाधान बदल रहा था $(this).offset().leftकरने के लिए this.offsetLeft
adjwilli 10

यह jQuery.position()एक 3 डी रूपांतरित माता-पिता के अंदर गलत व्यवहार को भी ठीक करता है , बहुत बहुत धन्यवाद!
रसो डे

6

मैंने इसे इंटरनेट एक्सप्लोरर में इस तरह किया।

function getWindowRelativeOffset(parentWindow, elem) {
    var offset = {
        left : 0,
        top : 0
    };
    // relative to the target field's document
    offset.left = elem.getBoundingClientRect().left;
    offset.top = elem.getBoundingClientRect().top;
    // now we will calculate according to the current document, this current
    // document might be same as the document of target field or it may be
    // parent of the document of the target field
    var childWindow = elem.document.frames.window;
    while (childWindow != parentWindow) {
        offset.left = offset.left + childWindow.frameElement.getBoundingClientRect().left;
        offset.top = offset.top + childWindow.frameElement.getBoundingClientRect().top;
        childWindow = childWindow.parent;
    }

    return offset;
};

=================== आप इसे इस तरह कह सकते हैं

getWindowRelativeOffset(top, inputElement);

मैं केवल अपने फोकस के अनुसार IE पर ध्यान केंद्रित करता हूं, लेकिन इसी तरह की चीजें अन्य ब्राउज़रों के लिए भी की जा सकती हैं।


1

ईवेंट की ऑफसेट को मूल तत्व ऑफ़सेट में जोड़ें इवेंट की पूर्ण ऑफ़सेट स्थिति प्राप्त करने के लिए।

एक उदाहरण :

HTMLElement.addEventListener('mousedown',function(e){

    var offsetX = e.offsetX;
    var offsetY = e.offsetY;

    if( e.target != this ){ // 'this' is our HTMLElement

        offsetX = e.target.offsetLeft + e.offsetX;
        offsetY = e.target.offsetTop + e.offsetY;

    }
}

जब ईवेंट टारगेट वह तत्व नहीं है, जिसे ईवेंट को पंजीकृत किया गया था, तो यह "निरपेक्ष" ऑफ़सेट मान की गणना करने के लिए वर्तमान इवेंट ऑफ़सेट में पैरेंट की ऑफ़सेट जोड़ता है।

मोज़िला वेब एपीआई के अनुसार: " HTMLElement.offsetLeft रीड-ओनली प्रॉपर्टी उन पिक्सेल की संख्या लौटाती है जो मौजूदा तत्व के ऊपरी बाएँ कोने में HTMLElement.offsetParent नोड के भीतर बाईं ओर ऑफसेट है। "

यह ज्यादातर तब होता है जब आप एक माता-पिता पर एक घटना दर्ज करते हैं, जिसमें कई और बच्चे होते हैं, उदाहरण के लिए: एक आंतरिक आइकन या टेक्स्ट स्पैन वाला एक बटन, liआंतरिक स्पैन वाला एक तत्व। आदि...


माता-पिता के पिता के बारे में क्या? स्क्रॉलबार वाले नेस्टेड तत्वों के बारे में क्या? प्रदर्शन के साथ पिछले तत्वों के बारे में क्या: कोई नहीं? एक सच्चे दस्तावेज़ ऑफसेट स्थिति की गणना करना लगभग असंभव है, फिर भी प्रतिपादन इंजन इसे जान सकता है। डॉम में दस्तावेज़ की स्थिति जैसे बहुत बुरे सरल गुण कभी शामिल नहीं किए गए थे।
डेविड स्पेक्टर

@DavidSpector शब्द

1

उदाहरण

इसलिए, अगर हमारे पास "चाइल्ड-एलिमेंट" की आईडी वाला चाइल्ड एलिमेंट है और हम इसे पाना चाहते हैं कि यह किसी पेरेंट एलिमेंट की तुलना में लेफ्ट / टॉप पोजिशन पर है, तो एक दिव्यांग का कहना है कि "आइटम-पैरेंट" की क्लास थी, हम इस कोड का उपयोग करें।

var position = $("#child-element").offsetRelative("div.item-parent");
alert('left: '+position.left+', top: '+position.top);

प्लगइन अंत में, वास्तविक प्लगइन के लिए (कुछ नोटों के विस्तार के साथ जो चल रहा है):

// offsetRelative (or, if you prefer, positionRelative)
(function($){
    $.fn.offsetRelative = function(top){
        var $this = $(this);
        var $parent = $this.offsetParent();
        var offset = $this.position();
        if(!top) return offset; // Didn't pass a 'top' element 
        else if($parent.get(0).tagName == "BODY") return offset; // Reached top of document
        else if($(top,$parent).length) return offset; // Parent element contains the 'top' element we want the offset to be relative to 
        else if($parent[0] == $(top)[0]) return offset; // Reached the 'top' element we want the offset to be relative to 
        else { // Get parent's relative offset
            var parent_offset = $parent.offsetRelative(top);
            offset.top += parent_offset.top;
            offset.left += parent_offset.left;
            return offset;
        }
    };
    $.fn.positionRelative = function(top){
        return $(this).offsetRelative(top);
    };
}(jQuery));

नोट: आप उपयोग कर सकते इस माउस क्लिक या माउसओवर घटना पर

$(this).offsetRelative("div.item-parent");

मैं स्क्रॉल करने के लिए जिम्मेदार नहीं देख रहा हूँ। बहुत सारे अजीब मामले हैं जो हो सकते हैं।
डेविड स्पेक्टर

1

मुझे एक और समाधान मिला। बच्चे की संपत्ति के मूल्य से मूल संपत्ति का मूल्य घटाएं

$('child-div').offset().top - $('parent-div').offset().top;

0

शुद्ध जेएस के साथ निश्चित रूप से आसान है, बस ऐसा करें, फिक्स्ड और एनिमेटेड एचटीएमएल 5 पैनल के लिए भी काम करें, मैंने इस कोड को बनाया और आजमाया है और यह किसी भी ब्राउजर के लिए काम करता है (IE 8 शामिल करें):

<script type="text/javascript">
    function fGetCSSProperty(s, e) {
        try { return s.currentStyle ? s.currentStyle[e] : window.getComputedStyle(s)[e]; }
        catch (x) { return null; } 
    }
    function fGetOffSetParent(s) {
        var a = s.offsetParent || document.body;

        while (a && a.tagName && a != document.body && fGetCSSProperty(a, 'position') == 'static')
            a = a.offsetParent;
        return a;
    }
    function GetPosition(s) {
        var b = fGetOffSetParent(s);

        return { Left: (b.offsetLeft + s.offsetLeft), Top: (b.offsetTop + s.offsetTop) };
    }    
</script>

क्या आपने मूल नोड्स और तत्व गुणों के सभी संभावित मामलों के साथ परीक्षण किया था? क्या स्क्रॉलिंग और नेस्टेड स्क्रॉलिंग के लिए यह खाता है?
डेविड स्पेक्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.