И опять про offsetLeft

sigurd

Новичок
И опять про offsetLeft

Сорри, если повторю уже много раз задаваемый вопрос. Стоит задача далеко не новая - определить координаты элемента на странице. Результаты поиска по форуму, инету, да и просто текущая рабочая версия сводятся к простому проходу по цепочке offsetParent до BODY с суммированием offsetLeft и offsetTop. Это уже много раз было, много раз проходилось и т.д. и т.п. и см. на обороте.

А теперь имеем страницу:
Код:
<div style="width: 500px; border: solid 1px red; padding: 10px;">
  <div id="inner" style="border: solid 1px green;">
    <a href="/">
      <img [b]align="right"[/b] id="testimg" height="15" width="15" src="myimage.jpg" border="0" />
    </a>
Текст текст текст текст текст текст текст 
текст текст текст текст текст текст текст 
текст текст текст текст текст текст текст 
текст текст текст текст текст текст текст 
текст текст текст текст текст 
  </div>
</div>
<script>
window.onload = function () {
  var obDiv = document.getElementById('inner');
  alert(obDiv.[b]offsetLeft[/b]);
}
</script>
FF, Opera, Safari выдают правильные значения, а вот IE всех доступных под рукой версий выдает в качестве значения offsetLeft отступ от первого дочернего элемента, то есть, от спозиционированной по правому краю картинки.

Есть предолжения, что с этим делать?
 

@ndrey

Новичок
1. боксовая модель ие (ие не добавляет к width значения border);
2. div id="inner" -> width:100%
 

sigurd

Новичок
/*1. боксовая модель ие (ие не добавляет к width значения border);*/
Это не проблема, поскольку погрешность на бордер вряд ли составит 460px, как в примере. А в приведенном коде бордеры добавлены сугубо для понятности картины.

/*2. div id="inner" -> width:100% */
Это уже выяснено экспериментально. Выстановка любого width кроме дефолтного auto дает верный результат. Проблема в том, что нужно общее решение, а div может иметь практически любое стилевое офомление или не иметь его вовсе...
 

@ndrey

Новичок
да баг именно с картинкой, не обратил внимание, что в ней собака зарыта.
тогда приходит на ум такая фигня: контейнеру поставить position:relative; а картинку располагать с position:absolute, т.е.:

#inner {....; positon:relative;}
#inner img {...; position:absolute; top:...; right:...;}
 

sigurd

Новичок
Я уже писал:
Проблема в том, что нужно общее решение, а div может иметь практически любое стилевое офомление или не иметь его вовсе...
То есть, нужно js-решение, не зависящее от верстки. Динамически изменять position элементов - это тоже не решение, а костыль.. ;-(
 

@ndrey

Новичок
ну а что тогда мешает посредством js определять браузер пользователя, если ие, то просматривать дочерние элементы блока и если там картинка, то делать соответствующие поправки на нее.

несколько минут кода.
 

sigurd

Новичок
ну а что тогда мешает посредством js определять браузер пользователя, если ие, то просматривать дочерние элементы блока и если там картинка, то делать соответствующие поправки на нее.
А вот тут и вступают в силу приколы типа боксовая модель ие (ие не добавляет к width значения border); или то, что div может иметь практически любое стилевое офомление. Картинка с выравниванием по правому краю - это частный случай, никто и никогда теперь не поручится за то, что оно не свалится на чем бы то ни было еще.

Да и по логике функционала я не должен никоим образом лезть в содержимое контейнера, и уж тем более, расставлять костыли на отдельные его варианты. Это другой уровень разработки, меня не касающийся. Грубо говоря, за содержимое отвечает некий дизайнер, а за динамику - я.

Было несколько вариантов обхода. Один из первых - это вставка промежуточного дива между наружным и #inner. IE7 это вариант проглотил, а вот IE6 поперхнулся. Другой вариант подразумевал обход необходимости вычисления координат, но он повешен на еще большее количество костылей, что очень не нравится. Наиболее изящным решением было бы кроссбраузерное определение координат с учетом вот таких вот косяков. Но пока что "не выходит каменный цветок" ;-(
 

@ndrey

Новичок
мне кажется в этом случае без костылей все равно не обойтись: либо вмешиваться менять стиль на кроссбраузерный (по сути задача дизайнера) либо костыли. Тем более
вставка промежуточного дива между наружным...
это изменение макета.
Если не вмешиваться в стиль, то можно решить задачу с использованием минимальных костылей, как вариант:
PHP:
function get_Real_Left_Offset(_obj)
 {
    var _offsetLeft;
    var _w;
    var obj=document.getElementById(_obj);
   // если браузер не IE
  if (navigator.userAgent.indexOf("MSIE")==-1)  return (obj.offsetLeft);
  else
 {
    _w =obj.style.width;
     if (_w=='auto' || _w=='') 
    {
      // временно меняем стиль
      obj.style.width='100%';
     _offsetLeft=obj.offsetLeft;
     // возвращаем обратно исходный стиль
     obj.style.width=_w;
     /*
       плюс (при необходимости) добавляем просчет
       толщины бордюра для родителя и потомка
        и исходя из этого формируем окончательный offsetLeft
     */
     }
     else _offsetLeft=obj.offsetLeft;
     
    return(_offsetLeft);
  }
 
 }
ЗЫ: вот к ней еще пара штрихов, и она может считать не только offsetLeft
 

sigurd

Новичок
Ага, как раз щас основная прорабатываемая версия - это временное изменение стиля контейнера #inner и вычисление offsetLeft на основе измененного, после чего, возвращение на круги своя...

Единственное, в приведенном коде
PHP:
_w =obj.style.width;
даст только инлайновый стиль, но это тоже легко обходится. Спасибо большое, щас буду реализовывать ;-)
 
Сверху