2011-03-28 6 views
5

페이지의 요소 좌표를 가져 오려고합니다.인라인 offsetparent를 사용하여 요소의 왼쪽/위쪽을 실제 가져 오기

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에 설명 된 사실에 기인한다 : jQuery를 함께하려고 몇 후

The element starts in the middle of the text

올바른 반환 -method 자신의 .offset() 오프셋 밝혀, 나는 소스를 보였지만 정확히 어떻게 찾을 수없는 것 그들은 그것을한다. 그래서 제 질문은 : 정확한 위치를 얻으려면 어떻게해야합니까? 이 프로젝트에서는 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 (즉, 왼쪽의 방법입니다 오프셋 화면이 명확하지 않음)

어떻게 가능합니까? 해결 방법은 없습니까? 근사값? 그것은 정확해야 할 필요는 없지만 이전보다 더 좋아야합니다. 감사.

편집 : 이것은 WebKit 렌더링 엔진을위한 것입니다.

답변

2

WebKit의 window.webkitConvertPointFromNodeToPage으로 끝났지 만 완전히 잘못된 위치를 반환하는 버그는 계속 발생했습니다. 추가 조사에 따르면 해당 노드가 표시 : 인라인이면 계층 구조의 마지막 블록 요소 위치가 반환됩니다.

이 이미지에 대한 해결책을 찾지 못했습니다 (웹킷의 소스 코드와 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) 
} 

을 인라인 자식의 오프셋 Top/Left를 가져 와서 부모로부터 뺍니다. 디스플레이가있는 부모에게 어떻게 작동하는지 잘 모르겠습니다. 인라인이지만 90 %는 작동합니다.

누구든지 더 좋은 아이디어가 있다면 나는 아직 제안을하고 있습니다.

1

아마도 herethe source code of jQuery.offset에서 사용 된 아이디어에 대한 설명을 찾을 수 있습니다. 당신이 here을 보면

당신은 offsetLeftoffsetTop 오래된 IE 버전에서 아주 정확하지 작동하는지 확인할 수 있습니다.

본인 또는 다른 것을 구현하는 방법을 이해하는 것이 흥미로운 일임을 이해합니다. jQuery.offset 함수의 소스 코드를 보는 것은 그렇게 쉽지 않습니다. 코드가 올바로 작동하고 브라우저에 독립적이되도록하려면 자체 구현을 작성하는 대신 jQuery.offset을 사용하는 것이 좋습니다.

1

webkitConvertPointFromNodeToPage 소스 코드를 살펴보면 요소 렌더러 개체를 사용하여 계산되고 해당 렌더러가없는 경우 렌더러가있는 neareset 조상을 사용합니다. 그러나 조상 렌더러를 사용하면 대상과 그 조상의 출처 사이의 기원 차이를 설명하기 위해 오프셋을 조정하지 않습니다. 즉, 포인트가 포함 렌더러를 기준으로 할 때 함수가 올바르게 작동 함을 의미합니다. 좌표를 계산하는 요소에 렌더러가없는 경우 offsetLeft/Top을 사용하여 가장 가까운 상위 항목으로 오프셋을 수동으로 조정해야합니다. 어떤 요소에 렌더러가 있는지 정확히 알기 위해서는 더 많은 연구가 필요하지만 일반적으로 콘텐츠가없고 SPAN과 같은 다른 노드의 표시에 영향을 미치는 요소는 렌더러가 필요하지 않습니다.

1

동일한 문제가 발생했습니다. $.offset().left을 jQuery와 함께 사용하면 단락 내의 단어 위치를 얻으려고합니다.

$(document).ready() 함수 안에 $.offset().left을 사용하면 잘못된 결과가 나타납니다.

$(window).load() 함수에서 $.offset().left을 사용하면 WebKit에서 내 문제가 해결되었습니다.

레이아웃에 영향을주는 이미지 요소 또는 글꼴이 떠 다니는 경우 특히 유용합니다.

관련 문제