2011-03-28 20 views
5

के साथ वास्तविक ऑफ़सेट तत्व के बाएं/शीर्ष प्राप्त करें मैं पृष्ठ पर किसी तत्व के निर्देशांक प्राप्त करने का प्रयास कर रहा हूं। मैं इसे प्राप्त करने के लिए मानक तरीका का उपयोग कर दिया गया है:इनलाइन ऑफ़सेटपेरेंट

var el = element, pos = {x: 0, y: 0}; 
while (el) { 
    pos.x += el.offsetLeft; 
    pos.y += el.offsetTop; 
    el = el.offsetParent; 
} 

लेकिन इस पद्धति असफल हो जाती है जब प्रश्न में तत्व display: block है, और offsetParents में से एक display: inline; है। इस तथ्य को this thread में वर्णित की वजह से है:

The element starts in the middle of the text

कुछ jQuery के साथ की कोशिश के बाद यह पता चला है कि उनके .offset() -method सही रिटर्न ऑफसेट, और मैं स्रोत के माध्यम से देखा है, लेकिन वास्तव में कैसे नहीं मिला वे करते हैं। तो मेरा सवाल है: मैं सही स्थिति कैसे प्राप्त करूं? मैं इस प्रोजेक्ट के लिए jQuery का उपयोग नहीं कर सकता, और the thread described earlier में विधि बोझिल है, एक तत्व जोड़ना और परीक्षण बहुत अधिक काम (प्रदर्शन परिप्रेक्ष्य) है, और Element.getBoundingClientRect का उपयोग या तो उपलब्ध नहीं है।

आप इसे आज़मा रहे आप Apple.com पर जा सकते हैं निम्नलिखित में चुनाव और प्रकार के अपने डिबगर खोलने की तरह महसूस करते हैं:

var el, el2; 
el = el2 = document.querySelector('#worldwide span'); 
var pos = {x: 0, y: 0}; 
while (el2) { 
    pos.x += el2.offsetLeft; 
    pos.y += el2.offsetTop; 
    el2 = el2.offsetParent; 
} 
alert("Calculated position: " + pos.x + "x" + pos.y + " window size: " + screen.width + "x" + screen.height); 
इस कोड के साथ

मैं:। Calculated position: 1354x988 window size: 1280x800 (यानी ऑफसेट बाईं का तरीका है स्क्रीन, जो यह स्पष्ट रूप से नहीं है)

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

संपादित करें: यह वेबकिट प्रतिपादन इंजन के लिए स्पष्ट करने के लिए है।

उत्तर

2

मैं वेबकिट के window.webkitConvertPointFromNodeToPage के साथ जा रहा था, लेकिन मैंने एक बग मार दिया जहां यह पूरी तरह से गलत स्थिति को वापस कर देगा। आगे की जांच से पता चला कि यदि प्रश्न में नोड प्रदर्शित किया गया था: इनलाइन, तो यह पदानुक्रम में अंतिम ब्लॉक तत्व की स्थिति वापस कर देगा।

इस छवि के लिए एक प्रस्ताव के लिए खोज कुछ भी नहीं हुआ (मुझे पता चला कि वेबकिट कॉनवर्टपॉइंटफ्रॉम नोड टोपेज वास्तव में क्या किया गया था और वेबकिट का स्रोत कोड)।

अनुमान लगाकर मुझे पता चला कि तत्व display: inline-block था, तो यह सही स्थिति लौटा, इसलिए यदि तत्व इनलाइन था तो मैंने इसे इनलाइन-ब्लॉक में बदल दिया और फिर स्थिति की गणना की।

अगर किसी के पास इस समस्या का बेहतर समाधान है तो मुझे आपसे सुनना अच्छा लगेगा!

संपादित करें:

प्रदर्शन शैली को बदलने इनलाइन-ब्लॉक करने के लिए हमेशा एक अच्छा विचार नहीं है बाहर कर देता है, तो बजाय कि मैं इस पद्धति का उपयोग कर रहा हूँ करने का:

var offset = {x: 0, y: 0}; 
if (getStyle(el, 'display') == 'inline') { 
    offset.x = el.offsetLeft - el.parentNode.offsetLeft; 
    offset.y = el.offsetTop - el.parentNode.offsetTop; 
} 

var point = window.webkitConvertPointFromNodeToPage(el, new WebKitPoint(0, 0)); 

return { 
    x: Math.round(point.x + offset.x), 
    y: Math.round(point.y + offset.y) 
} 

मैं इनलाइन बच्चे के ऑफसेट को ले जाना/बाएं और उसके माता-पिता से घटाना। मुझे सच में यकीन नहीं है कि यह उन अभिभावकों पर कैसे काम करता है जो प्रदर्शन करते हैं: इनलाइन, लेकिन यह 90% समय काम करता है।

लेकिन अगर किसी के पास कोई बेहतर विचार है तो भी मैं सुझावों के लिए खुला हूं।

1

शायद here आपको the source code of jQuery.offset में उपयोग किए गए विचारों का विवरण मिलेगा।

यदि आप here देखते हैं तो आप देख सकते हैं कि offsetLeft और offsetTop पुराने IE संस्करणों में काफी सही नहीं है।

मैं समझता हूं कि यह समझना दिलचस्प है कि यह या अन्य चीजों को कैसे कार्यान्वित किया जा सकता है। आप jQuery.offset फ़ंक्शन का स्रोत कोड कैसे देखते हैं, इतना आसान नहीं है। यदि आप चाहते हैं कि आपका कोड सही काम करता है और ब्राउज़र स्वतंत्र हो, तो आपको अपने स्वयं के कार्यान्वयन को लिखने के बजाय jQuery.offset का बेहतर उपयोग करना चाहिए।

1

वेबकिट का परीक्षणकॉन्टरपॉइंटफ्रॉम नोड टॉपेज स्रोत कोड से पता चलता है कि यह तत्व रेंडरर ऑब्जेक्ट का उपयोग करके गणना करता है, और यदि ऐसा कोई रेंडरर मौजूद नहीं है, तो यह नैनसेट पूर्वजों का उपयोग करता है जिसमें एक रेंडरर होता है। हालांकि, जब एक पूर्वजों के रेंडरर का उपयोग किया जाता है, तो यह लक्ष्य और उसके पूर्वजों की उत्पत्ति के बीच मूल भिन्नता के लिए ऑफसेट को समायोजित नहीं करता है। इसका अर्थ यह है कि जब फ़ंक्शन को रेंडरर के सापेक्ष दिया जाता है तो फ़ंक्शन सही तरीके से काम करता है। यदि आप जिस तत्व के लिए निर्देशांक की गणना कर रहे हैं उसके पास कोई रेंडरर नहीं है, तो आपको ऑफसेट को निकटतम पूर्वजों को मैन्युअल रूप से समायोजित करने की आवश्यकता है, जिसमें यह है (ऑफसेट लेफ्ट/टॉप का उपयोग करके)। यह जानने के लिए कि कौन से तत्वों को प्रस्तुतकर्ताओं को अधिक शोध की आवश्यकता होगी, लेकिन आम तौर पर कोई भी तत्व जिसमें कोई सामग्री नहीं है लेकिन स्पैन जैसे अन्य नोड्स के प्रदर्शन को प्रभावित करती है, को रेंडरर की आवश्यकता नहीं होती है।

1

मुझे एक ही समस्या थी जब jQuery के साथ $.offset().left का उपयोग करते हुए, अनुच्छेद के भीतर किसी शब्द की स्थिति प्राप्त करने का प्रयास किया गया।

का उपयोग $(document).ready() फ़ंक्शन के अंदर गलत परिणाम उत्पन्न हुआ।

$.offset().left$(window).load() फ़ंक्शन में वेबकिट में मेरी समस्या हल हो गई।

यह विशेष रूप से प्रासंगिक है जहां फ्लोट किए गए छवि तत्व या फोंट हो सकते हैं जो लेआउट को प्रभावित करेंगे।

संबंधित मुद्दे