Я не специалист по javascript, но уж очень нужно...
Вот скрипт, которым поделился один человечек. Скрипт работал только в Opera, я чуть подправил, тперь он работает и в IE и в Firefox =) Но есть одна проблема, в Firefox, как-то неправильно:
<SCRIPT language="JavaScript">
var ua = navigator.userAgent.toLowerCase();
isIE = (ua.indexOf("msie") != -1 && ua.indexOf("opera") == -1);
isOpera = (ua.indexOf("opera") != -1);
isGecko = (ua.indexOf("gecko") != -1);
isSafari = (ua.indexOf("safari") != -1);
isKonqueror = (ua.indexOf("konqueror") != -1);
document.onmousedown = OnMouseDown;
document.onmousemove = OnMouseMove;
document.onmouseup = OnMouseUp;
var stating = 0;
var DRAG=false;
function OnMouseDown(event)
{
if (event == null)
{
event = event||window.event;
}
target = event.target||event.srcElement;
action_obj = target.id;
if (isIE)
{
offsetY = event.offsetY;
}
else
{
offsetY = event.pageY - target.offsetTop;
}
distance = 0;
dragObjects = document.getElementById('drag').getElementsByTagName('*');
for (var i = 0; i < dragObjects.length; i++)
{
if(dragObjects[i].id == action_obj)
{
action_obj = i;
}
dragObjects[i].start = dragObjects[i].offsetTop; // Начальная расположение
dragObjects[i].height = dragObjects[i].clientHeight + 2; // Высота объекта с рамкой
}
if(stating == 0)
{
for(var i=0; i < dragObjects.length; i++)
{
dragObjects[i].style.position = 'absolute';
dragObjects[i].style.top = dragObjects[i].start;
}
stating = 1;
}
DRAG=true;
}
function OnMouseMove(event)
{
if(DRAG==true)
{
if (event == null)
{
event = event||window.event;
}
distance = 0; // При изменении координат мыши сбить счётчик пройденного
Y = event.clientY+document.body.scrollTop || event.clientY || event.pageY || event.y;
mouseY=parseInt(Y); // Координаты мышки при движении
dragObjects[action_obj].style.top = mouseY - offsetY - 5 + document.body.scrollTop; // Динамичное передвижение объекта за мышкой
dragObjects[action_obj].style.zIndex=2; // Чтобы работало везде
for(var i=0; i<dragObjects.length; i++)
{
if(i != action_obj)
{
var center_act_now = dragObjects[action_obj].offsetTop + dragObjects[action_obj].height/2; // Динамичное (постоянно меняющееся) расположение середны проверяемого
var center_cur = dragObjects[i].start + dragObjects[i].height/2; // Начальное расположение середны проверяемого
var center_cur_now = dragObjects[i].offsetTop + dragObjects[i].height/2; // Динамичное расположение середны проверяемого
// Если середина перетаскиваемого объекта сейчас ниже середины проверяемого И изначально была выше
if(center_act_now > center_cur_now && center_cur > dragObjects[action_obj].start)
{
// То поднять проверяемый на высоту перетаскиваемого
dragObjects[i].style.top = dragObjects[i].start - dragObjects[action_obj].height;
distance += dragObjects[i].height;
}
// И наоборот - если сейчас выше, а в начале была ниже
else if(center_act_now < center_cur_now && center_cur < dragObjects[action_obj].start)
{
// То опустить
dragObjects[i].style.top = dragObjects[i].start + dragObjects[action_obj].height;
distance -= dragObjects[i].height;
}
// Во всех противных случаях вернуть затронутые объекты их на начальные расположения
else
{
dragObjects[i].style.top = dragObjects[i].start;
}
}
}
}
return false; // Против выделения тескта при выдедении
}
function OnMouseUp(event)
{ // Действия после отпускания кнопки
dragObjects[action_obj].style.top = dragObjects[action_obj].start + distance; // Передвигаем ровно на высоту пройденных объекстов
dragObjects[action_obj].style.zIndex=1; // Для всех браузеров
save(); // Вычислить порядок элементов
DRAG=false;
}
function save()
{ // Сортировка элементов по их расположению и результат записываем в input
var dragSort = new Array();
var saveOutput = "";
for(var i=0; i<dragObjects.length; i++) dragSort[i] = Array(dragObjects[i].id, dragObjects[i].offsetTop);
dragSort.sort(function(i,ii){if (i[1] > ii[1]) return 1; else if (i[1] < ii[1]) return -1; else return 0;});
for(var i=0; i<dragObjects.length; i++) saveOutput += dragSort[i][0]+"|";
document.getElementById('save').value = saveOutput;
}
</script>
<style>
#drag *{cursor:move; border: 1px solid #ccc; background-color: #eee; width:200; height:20; z-index:1;}
.dragging {z-index:2; opacity:0.8; FILTER: Alpha(opacity=80);}
.draggingReset {z-index:1; opacity:1.0; FILTER: none;}
</style>
<BODY>
<div id=drag>
<div id=div1>div1</div>
<div style=height:50 id=div2>div2</div>
<div id=div3>div3</div>
<div id=div4>div4</div>
</div>
<input style=position:absolute;top:10;left:300 id=save value=result>
Проверял, проблема, вроде как возникает тут:
if(center_act_now > center_cur_now && center_cur > dragObjects[action_obj].start)
{
// То поднять проверяемый на высоту перетаскиваемого
dragObjects[i].style.top = dragObjects[i].start - dragObjects[action_obj].height;
distance += dragObjects[i].height;
}
// И наоборот - если сейчас выше, а в начале была ниже
else if(center_act_now < center_cur_now && center_cur < dragObjects[action_obj].start)
{
// То опустить
dragObjects[i].style.top = dragObjects[i].start + dragObjects[action_obj].height;
distance -= dragObjects[i].height;
}
// Во всех противных случаях вернуть затронутые объекты их на начальные расположения
else
{
dragObjects[i].style.top = dragObjects[i].start;
}
В Firefox почему-то страбатывает только условие ELSE