Большинство из вас, наверное, уже видели, как на некоторых сайтах, различные
элементы 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, прошу отписать ответ в комментах.
|