Перемещение объектов страницы мышкой

Опубликовано 30 марта, 2010 в JavaScript

Реализация возможности перетаскивания объектов веб-страницы мышкой (также, как вы передвигаете окна в ОС) может показаться достаточно сложной задачей. Но на самом деле все проще некуда.

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

Начнем с того, что подумаем, как можно мысль+движение рукой пользователя превратить в движение элемента. Для этого наша функция должна обрабатывать события: onmousedown (зажатие ЛКМ), onmousemove, (перемещение курсора), onmouseup (отжатие ЛКМ).

1)  onmousedown – функция активируется и создает событие onmousemove на весь документ
2) onmousemove – функция отслеживает координаты курсора, пока курсор движется, задает элементу эти координаты, элемент движется вместе с курсором.
3)  onmouseup – функция деактивируется.

Теперь переходим к практике.

function move_me(e) {
    //Отлавливаем координаты в момент onmousedown
    if(!e) e = window.event;
    x = e.pageX || e.x;
    y = e.pageY || e.y;
    elem = document.getElementById('moveme'); //Указываем на наш элемент
    //Вешаем на документ правила для передвижения курсора
    document.onmousemove = function(e) {
        //Отлавливаем координаты
        if(!e) e = window.event;
        var x2 = e.pageX || e.x;
        var y2 = e.pageY || e.y;
        //Задаем эти координаты элементу
        elem.style.top = y2+'px';
        elem.style.left = x2+'px';
    }
    document.onmouseup = function() {  document.onmousemove = null; };
}

Теперь осталось только создать слой moveme и повешать на него событие onmousedown:

<div id="moveme" style="width: 100px; height: 100px; background-color: #333; position: absolute;" onmousedown="move_me(event);">

Готово. Смотрим на результат.

Как видите, ничего сложного нет, каких-то 12 строк кода. Перемещать по страничке таким способом можно любые элементы, где это может пригодиться – додумайте сами.

Спустя почти год: случайно наткнулся на пост, так и не понял, а нафиг первые 3 строки внутри move_me и передача функции event? оО? Наверно, было скопировано с какого-то проекта. Можно смело убирать отлов координат в момент onmousedown, останется 9 строк:

function move_me() {
    elem = document.getElementById('moveme'); //Указываем на наш элемент
    //Вешаем на документ правила для передвижения курсора
    document.onmousemove = function(e) {
        //Отлавливаем координаты
        if(!e) e = window.event;
        var x2 = e.pageX || e.x;
        var y2 = e.pageY || e.y;
        //Задаем эти координаты элементу
        elem.style.top = y2+'px';
        elem.style.left = x2+'px';
    }
    document.onmouseup = function() {  document.onmousemove = null; };
}



Комментарии «Перемещение объектов страницы мышкой»:
Комментариев: 29. Обязательно оставьте свой!
Severus 08.04.2010 в 23:18

Автор,ты крут)Не,я видел drag`n`drop,но все они были такие длинные строки кода…что ппц.Вообщем,мне нравится)Спс.

sk___ 27.04.2010 в 14:51

Вот так – не дергается при нажимании левой кнопки мыши:

<html>
<head>
<script type=
"text/javascript">
var xshift = 0;
var yshift = 0;
function move_me(e) {
 if(!e) e = window.event;
 x = e.pageX || e.x;
 y = e.pageY || e.y;
 elem = document.getElementById('moveme');
 xshift = x-elem.style.left.substring(0,elem.style.left.length-2);
 yshift = y-elem.style.top.substring(0,elem.style.top.length-2);
 document.onmousemove = function(e) {
  if(!e) e = window.event;
  var x2 = e.pageX || e.x;
  var y2 = e.pageY || e.y;
  y2 = y2-yshift;
  x2 = x2-xshift;
  elem.style.top = y2 + "px";
  elem.style.left = x2 + "px";
 }
 document.onmouseup = function() {
 document.onmousemove = null;
};
}
</script>
</head>
<body>
<div id="moveme" style="left:0px; top:0px;width: 100px; height: 100px; background-color: #333; position: absolute;" onmousedown="move_me(event);">

</div>
</body>
</html>

в 11.07.2010 в 7:29

Удалите вот этот код где не дергается – какой то даун выложил нихрена не рабочее говно.

в 11.07.2010 в 7:29

юзер sk___, который оставил

pistol 11.07.2010 в 8:14

Не, нормальный рабочий код. Просто толи сам автор, толи двиг сайта, поставил дебильные кавычки. Исправил.

в 14.07.2010 в 17:50

Исправлял кавычки, все равно не работает.

в 14.07.2010 в 17:52

Почему на 3-ем перетаскивании в FF например, появляется значок "стоп"? и далее картинка тупо прилипает к курсору когда даже мышь не нажата: то есть просто водишь ей туда сюда и за ней квадратик ездеет. Уже и выход из функции поставил.. обнулил все переменные… не пойму.

в 14.07.2010 в 17:56

Да и на 2-ом перетаскивани тоже бывает..

в 14.07.2010 в 17:57

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

pistol 14.07.2010 в 18:06

> Исправлял кавычки, все равно не работает.

Точно, только в опере работало. Еще правки внес, теперь и в фф.

В ФФ 3.6.6 ubuntu не наблюдаю значка стоп. Однако если очень быстро перемещать объект, то вместо самого объекта перемещается его "образ", который создает браузер (такой же, как при перетаскивании картинок). Когда-то занимался этой проблемой, как решил ее уже забыл.

в 14.07.2010 в 19:35

>вместо самого объекта перемещается его "образ"
ну да, у вас только значка стоп нет.

>Когда-то занимался этой проблемой, как решил ее уже забыл.
Хотя-бы пример, где эта проблема решена, было бы здорово.

в 14.07.2010 в 20:07

&nbsp; в див который таскаем.
По сути диву нужен элементарный контент, тогда все гуд.

Anton 14.07.2010 в 20:25

И конечно задать font-size:0; line-height:0;
Чтобы не выделялся этот пробел.

kostya1306 28.10.2010 в 4:19

В IE7 не работает.

kostya1306 28.10.2010 в 6:43

Я разобрался! Для уверенности надо добавить onmousedown=»move_me(event); return false;», и чтоб не появлялся значек стоп надо добавить ondragstart=’return false;. В моем случае получилось: Проверено в IE7, IE9, Opera, FF.

kostya1306 28.10.2010 в 6:46

Блин, не знаю как тего здесь оформлять… Вот что в моем случае получилось:
img src=’image.jpg’ alt=» height=’400′ class=’layer2′ id=’fich’ ondragstart=’return false;’ onmousedown=’move_me(event); return false;’

Рома 08.11.2010 в 15:54

а можно ли сделать так, чтобы координаты задавались не пикселями, а ячейками таблицы: например у меня таблица 8х8, рисунок находится в ячейке 1х1, и я хочу перетащить его в ячейку , например 3х7. Если так можно сделать, буду очень признателен)

ddd 28.02.2011 в 2:30

Никита 28.02.2011 в 2:35

В этом уроке наблюдаются баги на Mozilla FireFox. А так же при нажатии на объект он переносится на координаты курсора. Выход нашел на в этом уроке Перемещение объектов по рабочей области. Там все доступно показано. Но и это обьяснение мне очень помогло

ixley 14.04.2011 в 0:18

А как сделать так чтобы передвинутое так и оставалось в том же положении куда его и передвинули? Заранее спасибо.

pistol 14.04.2011 в 7:42

ixley, оставалось после обновления страницы?

Никита 27.06.2011 в 14:01

ixley, что бы оставалось на месте, куда передвинули, координаты можно записывать куки, что бы после загрузки страницы и обработки скрипта объект находился на координатах из кук

maxim 20.09.2011 в 15:33

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

Olga 04.11.2011 в 17:38

Привет. С квадратом все получилось отлично, но как вместо квадрата поставить несколько изображений букв, чтоб дети могли составлять слова?
Помогите правильно прописать, пожалуйста.
Заранее спасибо )))

pistol 04.11.2011 в 18:40

Olga, нужно <div id="moveme" заменить на <img id="moveme" src="123.png"

Чтобы не писать для каждого img свою функцию, можно ID каждой картинки передавать во 2 параметре функции move_me

Olga 05.11.2011 в 19:44

Спасибо за ответ!
Пока не получилось с перемещением… пробу можно посмотреть в центральном виджете тут – http://prima.forum2x2.ru/
html:

Olga 05.11.2011 в 19:45

Код html, к сожалению, не поместился, но я думаю, что вы увидели там таблицу и дивы

pistol 06.11.2011 в 16:19

Ольга:

<script type="text/javascript">
function move_me(e, id) {
  elem = document.getElementById(id);
  elem.style.position = 'absolute';

  document.onmousemove = function(e) {
    if(!e) e = window.event;
    var x2 = e.pageX || e.x;
    var y2 = e.pageY || e.y;
    elem.style.top = y2+'px';
    elem.style.left = x2+'px';
  }
  document.onmouseup = function() {  document.onmousemove = null; };
}
</script>

<img id="moveme1" src="http://modelmen.ru/font_maker/4/font/-a.gif" onmousedown="move_me(event, 'moveme1');">
<img id="moveme2" src="http://beluys.com/alfavit/bukva32.gif" onmousedown="move_me(event, 'moveme2');">
<img id="moveme3" src="http://fantasyflash.ru/anime/bukva/image/bukva57.gif" onmousedown="move_me(event, 'moveme3');">
Olga 06.11.2011 в 19:43

Спасибо, теперь все работает!
Осталось понять, что надо прописать и КУДА…чтоб не появлялся значок «стоп»? )))

Ваш комментарий: