Зачем это нужно? Например, чтобы создать красивый выпадающий список. Сегодня мы зададимся целью создать некий пользовательский комбо-бокс. И стандартные возможности HTML нас не устраивают. То есть, мы хотим получить нечто более сложное, чем вот это.
<option>Item 1</option>
<option>Item 2</option>
<option>Item 3</option>
</select>
А получить хотели бы нечто вроде этого:
<div style="’border:" 1px solid #072; background-color: #59E75D; width: 100px;’ id=’list1′>
<ul>
<li><a href=’#'>Item 1</a></li>
<li><a href=’#'>Item 2</a></li>
<li><a href=’#'>Item 3</a></li>
</ul>
Вообще, для позиционирования элемента в координатах, заданных своими величинами (X, Y) подойдет вот такая функция:
if(obj) {
obj.style.position=’absolute’;
obj.style.left=x+’px’;
obj.style.top=y+’px’;
}
}
Эта функция проста и особых пояснений не требует. Осталось только правильно определить координаты того элемента(E1), относительно которого хочется спозиционировать заданный элемент(E2), да еще и в соответствии с тем, к какому именно углу E1 будет пристыкован E2. Углов у любого прямоугольника всего 4. Соответственно и вариантов позиционирования будет 4. Вот они.
Функция getBounds определяет параметры left, top, width, height объекта. Цикл while нужен для того, чтобы определить абсолютные координаты объекта относительно контейнера <body>.
var w=obj.offsetWidth;
var h=obj.offsetHeight;
var x=y=0;
while(obj){
x+=obj.offsetLeft;
y+=obj.offsetTop;
obj=obj.offsetParent;
}
return{x:x,y:y,width:w,height:h};
}
Ну а вот и сама функция позиционирования:
// anc_id - id элемента, относительно которого будем позиционировать
// obj_id - id элемента, который будем позиционировать
// corner - номер угла (смотрите Рис.1)
// margin - отступ между элементами, чтобы они не “слипались”
if(!corner)corner=1;
var obj=document.getElementById(obj_id);
var anc=document.getElementById(anc_id);
if(!obj||!anc) return;
var b=getBounds(anc);
var c=getBounds(obj);
var xs=0,ys=0; // координаты left и top родительского элемента (на случай, если кто-то из родителей абсолютно позиционирован)
var par=obj;
for(var i=0;i<50;i++){
par=par.parentNode;
if(!par||par.tagName==’BODY’) break;
var s=getCurrentStyle(par);
if(par.tagName==’DIV’&&s&&s.position==’absolute’){
var p=getBounds(par);
xs+=p.x
ys+=p.y;
break;
}
}
var xc=0,yc=0; // Дополнительные отступы, учитывающие номер угла
switch(corner){
case 2:
yc=-c.height-b.height;
break;
case 3:
yc=-c.height-b.height;
xc=-c.width;
break;
case 4:
xc=-c.width+b.width;
break;
}
var xm=0;ym=0; // Дополнительные отступы, учитывающие параметр margin
if(margin){
xm=margin.x;
ym=margin.y;
}
SetPosXY(obj,b.x-xs+xc+xm,b.y+b.height-ys+yc+ym);
}
И чуть не забыл, функция getCurrentStyle нужна, чтобы кроссбаузерно определить текущий стиль элемента:
if(!el) return null;
var s=el.currentStyle;
if(!s) s=document.defaultView.getComputedStyle(el,null); // Для FireFox
return s;
}
А вот здесь находится весь скрипт. Пользуйтесь на здоровье.
Ну а вызов этой функции может выглядеть так: