Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Как узнать координаты элемента?


Автор: dr.ZmeY 20.8.2004, 01:52
Сабж... Любого элемента, формы, картинки, слоя, таблицы ... разумеется обладающего ID... Т.е. кроме его ID, не известно, где на странице он раположен (а иногда и браузеры коверкают дизайн)...
Добавлено @ 01:53
Оч... нужно. Желательно код (без раницы под какой браузер, сам дальше разрулю)...
Спасибо

Автор: Sardar 20.8.2004, 02:00
Так можно:
Код
function getPosition(obj) {
var x=0, y=0;
while(obj) {
   x+=obj.offsetLeft;
   y+=obj.offsetTop;
   obj=obj.offsetParent;
}
return {x: x, y:y};
}

Но IMHO немного изврат напоминает, может задачу лучше опишешь, возможно без всяких корректировок позиций элементов обойдемся.

Автор: dr.ZmeY 20.8.2004, 02:15
Не а... Слои выставляются яваскриптом, подгружаемым в дизайн сайта. В зависимости от наполнености контентом эта вставка меняет своё положение на странице (в ней есть как таблицы с картинками, так и слои) и если с таблицами и картинками ничего не случится, то слои "уплывают"... вот я и хочу привязать их к конкретным элементам.

Автор: Sardar 20.8.2004, 15:38
Ну по любому координаты x/y ты кодом выше получишь.
Цитата(dr @ 20.8.2004, 01:15)
вот я и хочу привязать их к конкретным элементам

Вот это не совсем понял... как привязать?

Автор: dr.ZmeY 22.8.2004, 01:17
Т.е. я буду вычислять координаты слоя, по полученным координатам данного элемента..
Цитата(Sardar @ 20.8.2004, 16:38)
Ну по любому координаты x/y ты кодом выше получишь.

Т.е.? на сколько выше и в каких браузерах, чтобы можно было ввести поправку на погрешность...

Автор: Sardar 22.8.2004, 13:13
dr.ZmeY по моему мы друг друга не понимаем smile.gif

В свойствах offset(Left|Top) хранится смещение обьекта относительно предка offsetParent, у предка в свою очередь тоже есть предок и т.д. Таким образом ты можешь вычислить положение любого элемента относительно другого элемента. Просматривать нужно до элемента HTML. Узнать на каком теге мы сейчас можно через элемент.nodeName

Теперь конкретней что нужно(если еще нужно smile.gif ), по заданному обьекту узнать его слой и координаты слоя?
Код
<!-- несущий слой, промаркирован классом container -->
<div class="container"><table><tr><td id="test">Hoi</td></tr></table></div>
<script language="Javascript" type="text/javascript">
<!--
//функция возвращает несущий слой и его координаты по заданному элементу
function getPlatf(obj) {
while(obj&&!(obj.nodeName=="DIV"&&obj.className=="container")) obj=obj.parentElement;
if(!obj) return null;
var x=0, y=0, tg=obj;
while(obj) {
  x+=obj.offsetLeft;
  y+=obj.offsetTop;
  obj=obj.offsetParent;
}
// возвращаем обьект в полях которого: target - несущий слой, x/y - координаты
return {target: tg, x: x, y:y};
}
var r=getPlatf(document.getElementById("test")); //вычислим для ячейки таблицы
alert(r.target.nodeName+", "+r.x+", "+r.y);
//-->
</script>

Автор: Иль 10.7.2005, 20:16
Эх, жаль нет в ИЕ у элементов свойств .x и .y как в Gecko, с координатами относительно HTML. Ну да ладно. Спасибо за код, Sardar, задействую его под ИЕ, а то уж хотел события генерить, чтоб получить координаты. Я сначала тоже мыслил в направлении твоего решения, но потом здался, как заметил некую путаницу в размерах, а видать надо offsetParent применять было. Как раз про него я и не знал. Ну а репа, а репа потом, сегодня уже репил smile

Автор: Sardar 10.7.2005, 20:52
Цитата
как заметил некую путаницу в размерах, а видать надо offsetParent применять было.

Я точно не помню, но по моему offsetParent был придуман до CSS'овского box model. Поле указывает напервый внешний блочный элемент с релативной позицией, от которого отсчитываються координаты текущего элемента. Обычно это body.


Цитата
Ну а репа, а репа потом, сегодня уже репил smile

Пысыб большой, из-за тебя у меня репа в небеса взлетела, другим участникам сложнее будет догнать, пора бы сбросить темпы smile

Автор: Иль 10.7.2005, 23:53
Я слово дал, как сотню наберу все репы раздам, никого не забуду. Я ж не виноват, что твоих столько набралось, все по справедливости (хотя мож действительно надо было учебник почитать)
В неоплатном долгу перед тобой и Aliance. До сих пор в себя прейти не могу, как все класно получилось сделать!!!

Автор: Иль 13.7.2005, 12:08
Минуточку, я хочу уточнить.
А что, нельзя пользоваться без offsetParent, а используя только offsetTop и все, например: .offsetTop + .perentNode.offsetTop + ... и так до body, где .perentNode=null. Вот у меня так чего-то не получалось, правда smile

Автор: Sardar 13.7.2005, 15:44
Нет нельзя, offsetParent и parentNode это два разных понятия.
parentNode это родительский элемент, то куда наша нода вложенна. offsetParent это первый элемент от которого считаються координаты. Если ты не использовал элементов на релативной позиции, то весь документ будет иметь offsetParent = body.

Идея offsetParent в том, что сдвигая элемент который для других элементов являеться offsetParent'ом, ты автоматом сдвигаешь всех. Обычно всякие менюшки вкладывают в слои с релативной позицией, дабы координаты не расчитывать, а ставить в left: 0, top:0

Считая координаты от parentNode ты должен был получать огроменные результаты smile

Автор: Иль 13.7.2005, 18:44
Цитата(Sardar @ 13.7.2005, 15:44)
сдвигая элемент который для других элементов являеться offsetParent'ом, ты автоматом сдвигаешь всех

Слушай, Sardar, это СУПЕР!!!!!!!!!!!!!
Сразу мысли забурлили в голове smile

Автор: Иль 13.7.2005, 18:57
Цитата(Sardar @ 13.7.2005, 15:44)
Считая координаты от parentNode ты должен был получать огроменные результаты

Ага, просто обалденные smile

Автор: Sardar 13.7.2005, 19:52
Цитата
Слушай, Sardar, это СУПЕР!!!!!!!!!!!!!

На этом примере думаю будет ясно как это на практике smile

Код
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
    <title>Galaxy - test</title>
<style type="text/css">
#flycont {
  position: absolute;
  width: 40%;
  height: 20%;
  border: solid 1px navy;
}

#ct {
  position: relative;
  width: 100%;
  height: 100%;
}
.shp {
 position: absolute;
 border: 1px solid navy;
 width: 20px;
 height: 20px;
}
</style>
<script type="text/javascript">
function mdown(e) {
  this.dragging=true;
  this.offX=(window.event? window.event.offsetX: e.layerX)+3;
  this.offY=(window.event? window.event.offsetY: e.layerY)+3;
  var evt=window.event? window.event: e;
  if(evt.stopPropagation) evt.stopPropagation();
  evt.cancelBubble=true;
}
function mup() {
  this.dragging=false;
  var evt=window.event? window.event: e;
  if(evt.stopPropagation) evt.stopPropagation();
  evt.cancelBubble=true;
}
function mmove(e) {
  if(!this.dragging) return false;
  var evt=window.event? window.event: e;
  var x=0, y=0, ofp=this.offsetParent;
  while(ofp!=null) {
    x+=ofp.offsetLeft;
    y+=ofp.offsetTop;
    ofp=ofp.offsetParent;
  }
  this.style.left=(document.body.scrollLeft+evt.clientX-this.offX-x)+"px";
  this.style.top=(document.body.scrollTop+evt.clientY-this.offY-y)+"px";
  if(evt.stopPropagation) evt.stopPropagation();
  evt.cancelBubble=true;
  return true;
}
function minit(o) {
  o.onmousedown=mdown;
  o.onmouseup=mup;
  o.onmousemove=mmove;
  o.onselectstart=function(){return false;};
}
</script>
</head>

<body>
<div id="flycont"><div id="ct"></div></div>
<script type="text/javascript">
<!--
minit(document.getElementById("flycont"));
var c=document.getElementById("ct");
var row=c.offsetHeight;
var cc=0, cl=0, r=false;
while((row-=25)>0) {
  cl=-20; cc++; r=true;
  while((cl+=25+(cc%2&&r? 10: 0))<c.offsetWidth-20) {
    r=false;
    var sh=document.createElement("SPAN");
    sh.className="shp";
    sh.style.left=cl+"px";
    sh.style.top=row+"px";
    sh.style.backgroundColor=((cl+cc)%2? "red": "blue");
    c.appendChild(sh);
    minit(sh);
 }
}

//-->
</script>

</body>
</html>


Хватаем мышью за любые квадратики и тащим куда угодно. Затем тащим рамочку, наблюдаем за эффектом.

Звыняюсь под Оперой скорее всего не будет работать, у всех трё типов браузеров(ИЕ, Опера, Мозилла) по разному координаты высчитываються, а Оперы под рукой нет что бы проверить и фиксить.

Автор: Иль 5.8.2005, 20:05
Цитата(Sardar @ 13.7.2005, 19:52)
if(evt.stopPropagation) evt.stopPropagation();
  evt.cancelBubble=true;

Sardar, почему не пользуешся только cancelBubble, из-за правил хорошего тона smile ?
Добавлено @ 20:10
Цитата(Sardar @ 13.7.2005, 19:52)
function mup() {

35 строка пропустил аргумент функции e
Опять ты мне шикарную идею подкинул!!! Спасибо большое за пример
Добавлено @ 20:12
Жаль в Gecko все работает с тормазами, но это можно поправить размерами элементов

Автор: Sardar 5.8.2005, 22:15
Цитата
Sardar, почему не пользуешся только cancelBubble, из-за правил хорошего тона

Нет, просто следую стандартам W3C, a cancelBubble не в стандарте. Винить ИЕ не нужно, парни молодцы, ещё до выхода каких либо "стандартов" они уже давно имеют "новые" фичи smile

Цитата
Жаль в Gecko все работает с тормазами

А нечго анимации делать на таких сложных элементах как разметка в браузере smile
И вообще мозилла как Сафари даёт тебе в руки <canvas> тег с релизом 1.1, вот там рисуй и анимируй что угодно smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)