Перетаскивание объектов в HTML средствами JS (Drag & Drop)


Большинство из вас, наверное, уже видели, как на некоторых сайтах, различные элементы HTML-верстки можно «ухватить мышой» и перетащить в другое место на странице. Это называется «drag and drop», а если дословно, то «схвати и тащи». В статье я расскажу, как, при помощи небольшого куска кода на Javascript, реализовать подобный функционал на своём сайте. Итак, поехали.

Во-первых, для того, чтобы объекты на страницы могли свободно перемащаться, независимо от соседних элементов, мы выставим им абсолютное позиционирование (position:absolute) и начальные координаты (left и top) в CSS.
Во-вторых, главным участником всех действий в JS, послужит конечно-же стандартный объект window.event, при помощи которого мы будет определять координаты объекта.
В целом, замысел будет таков: по клику левой кнопкой мыши на объекте мы устанавливаем «флаг» (obj.clicked = true) на объект (HTML DOM-элемент), означающий что «объект выбран и можно инициализировать его перемещение». В дальнейшем, после этого действия, все перемещения указателя по экрану на странице сайта, будет отрабатывать метод document.onmousemove, в котором мы: получаем новые координаты перемещаемого объекта, меняем его позицию для «left и top» CSS-свойств.
Для клика по объекту, будет использовано событие onmousedown, вместо onclick, т.к оно срабатывает раньше и не требует отпускания кнопки мыши. После того, как мы переместили объект в нужную позицию на странице и отпустили кнопку мыши, срабатывает событие document.onmouseup и убирает значение флага (obj.clicked = false).
Также, для того чтобы избежать всяческих глюков с тем, когда при перемещении объекта браузер по умолчанию обрабатывает свои встроенные события, мы будем вызывать метод объекта event — preventDefault(). Данный скрипт тестировался и отлично себя повел в Opera 9+, Firefox 2+, Safari 2, Google Chrome, а вот в IE (6,7) хотя перетаскивание и работает, но довольно-таки глючно (в этих версиях IE у объекта event нету метода preventDefault, хотя есть свойство returnValue, что должно выполнять посути туже функцию, но оно почему-то не помогло).
Код функции для перетаскивания объектов привожу ниже:

function drag_object( evt, obj )
{
evt = evt || window.event;

// флаг, которые отвечает за то, что мы кликнули по объекту (готовность к перетаскиванию)
obj.clicked = true;

// устанавливаем первоначальные значения координат объекта
obj.mousePosX = evt.clientX;
obj.mousePosY = evt.clientY;

// отключаем обработку событий по умолчанию, связанных с перемещением блока (это убирает глюки с выделением текста в других HTML-блоках, когда мы перемещаем объект)
if( evt.preventDefault ) evt.preventDefault();
else evt.returnValue = false;

// когда мы отпускаем кнопку мыши, убираем «проверочный флаг»
document.onmouseup = function(){ obj.clicked = false }

// обработка координат указателя мыши и изменение позиции объекта
document.onmousemove = function( evt )
{
evt = evt || window.event;
if( obj.clicked )
{
posLeft = !obj.style.left ? obj.offsetLeft : parseInt( obj.style.left );
posTop = !obj.style.top ? obj.offsetTop : parseInt( obj.style.top );

mousePosX = evt.clientX;
mousePosY = evt.clientY;

obj.style.left = posLeft + mousePosX - obj.mousePosX + 'px';
obj.style.top = posTop + mousePosY - obj.mousePosY + 'px';

obj.mousePosX = mousePosX;
obj.mousePosY = mousePosY;
}
}
}


Функцию также можно доработать, чтобы она запоминала координаты. Для этого нужно всего лишь их устанавливать в методе document.onmouseup, при помощи функции для установки куков, которую также привожу ниже:

function setcookie( name, value, timeout )
{
timeout = timeout || 1000*60*60*24;
expires = (new Date((new Date).getTime() + timeout)).toUTCString();
document.cookie = name + '=' + value + ';expires=' + expires;
}


И в дальнейшем, чтобы использовать установленные координаты объектов, записанные в кукисах, их нужно получать, обрабатывать и устанавливать после загрузки всех HTML-блоков, для которых были установлены координаты, или же выполнять эту же функцию по событию widnow.onload.
Скрипт парсинга куков и установки координат не привожу, сами уже разберетесь, кому надо. Если у кого есть советы или пожелания по скрипту в целом, или по тому, как исправить глючность скрипта в Internet Explorer, прошу отписать ответ в комментах.

Посмотреть работу скрипта на примере | Скачать в архиве

01.11.2009 / javascript, кодинг, ie6
Понравилась статья?
Подпишись на рассылку через RSS или следуй за нами в Twitter!
Похожие статьи:
Оценка статьи: проголосовало - 14, средняя оценка - 4,71
Комментарии к статье (7):
[ 05.09.2010 - 21:50 ] - КостяН('master');
отлично!!!по больше бы таких!
[ 07.09.2010 - 15:55 ] - virus
отлично!!!!!!!!!!!!!!!!!
спасибо:))))))))))))
[ 02.11.2010 - 14:15 ] - NxN
Супер!
[ 31.01.2011 - 16:30 ] - Olezhik
Спасибо! Все работает!
[ 29.07.2011 - 23:02 ] - vkz
уточните по-поводу куков. руки не от-туда, нихрена не выходит)
[ 23.11.2011 - 18:15 ] - Виктор
Установка кук
function setk(name, value, expires, path, domain, secure) {
document.cookie =
name +"=" + escape(value) +
((expires) ? "; expires=" + expires.toGMTString() : "") +
((path) ? "; path=" + path : "") +
((domain) ? "; domain=" + domain : "") +
((secure) ? "; secure" : "")
}
Чтение кук
function getk(name) {
prefix = name + "=";
cookieStartIndex = document.cookie.indexOf(prefix);
if (cookieStartIndex == -1)
return null
cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + prefix.length);
if (cookieEndIndex == -1) cookieEndIndex = document.cookie.length;
return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex));
}
[ 07.02.2012 - 16:14 ] - asd
asd
Добавить комментарий
АНТИСПАМ: Выберите улыбающийся смайл: yep! nope! nope!
Оформление заявки
Файл>>