Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
Программируем перетаскиване(Drag and Drop) на JavaScript
Иногда разработчик сталкивается с необходимостью разрешить пользователю свободно перемещать некоторые объекты на странице. Например, такая ситуация возникает при программировании некоторых JavaScript-игр. В этой статье изложена общая теория программирования драга на JavaScript.
Сделать это можно, задав обработчики событий: ondragstart, ondrag, ondragend - для перемещаемого объекта. Но drag-события поддерживаются не всеми версиями современных браузеров. Поэтому мы реализуем универсальную систему, используя обработчики событий onmousedown, onmousemove и onmouseup. Обратите внимание, что при использовании этих событий можно установить любую форму курсора.
Кроме этого мы отключим стандартный обработчик события oncontextmenu, которое возникает при нажатии правой кнопки мыши и приводит к выводу на экран контекстного меню.
Нам нужно установить параметр position в значение absolute и задать начальные координаты.
Исходный код этого примера:
<img
src="../plane1b.gif"
alt='Перемещаемый объект'
style="position:absolute;left:100px;top:100px;cursor:move;"
onMousedown="DD.start(event)"
oncontextmenu="return false"
ondragstart="return false"
ondragend="return DD.stop()"
>
<img class='drag'
src="../plane2b.gif"
alt='Перемещаемый объект'
style="position:absolute;left:220px;top:100px;cursor:move;"
>
<img class='drag'
src="../plane2b.gif"
alt='Перемещаемый объект'
style="position:absolute;left:280px;top:150px;cursor:move;"
>
<script type="text/javascript">
var DD = {
start: function(e) {
if(typeof DDmove == 'boolean' && DDmove)return false;
DDobj=getEventTarget(e);
//if(!DDobj.className=='DRAG')return true;
DDx=parseInt(DDobj.style.left) - (document.all? event.clientX : e.clientX)
DDy=parseInt(DDobj.style.top) - (document.all? event.clientY : e.clientY)
DDmove=true
//document.onmousemove=DD.drag_drop
addEvent(document, 'mousemove', DD.drag_drop)
addEvent(DDobj, 'mouseup', DD.stop)
//addEvent(DDobj, 'dragstart', DD.f)
//addEvent(DDobj, 'dragend', DD.stop)
//addEvent(DDobj, 'dragend', DD.stop)
DDobj.style.zIndex=100; // сделать верхним
//addEvent(DDobj, 'selectstart', DD.f, true);
},
stop: function(e) {
DDmove=false
//document.onmousemove=null
removeEvent(document, 'mousemove', DD.drag_drop)
removeEvent(DDobj, 'mouseup', DD.stop)
DDobj.style.zIndex=0;
return true
},
drag_drop: function(e) {
if (document.all&&DDmove){
DDobj.style.left=DDx+event.clientX
DDobj.style.top =DDy+event.clientY
return false
}
else if (document.getElementById&&!document.all&&DDmove){
DDobj.style.left=DDx+e.clientX+"px"
DDobj.style.top =DDy+e.clientY+"px"
return false
}
},
init: function(c) {
el=getElementsByClass('drag');
for ( i=0;i < el.length;i++ ) {
DDobj=el[i];
addEvent(DDobj, 'mousedown', DD.start);
addEvent(DDobj, 'contextmenu', DD.f, true);
DDobj.draggable=false;
}
},
f:function(e){
e = e || window.event
if(e && e.stopPropagation) e.stopPropagation(); // для DOM-совместимых браузеров
else window.event.cancelBubble = true; //для IE
return false},
t:function(e){return true}
}
DD.init();
</script>
- Класс "Drag and Drop" имеет следущие методы:
- DD.start - нажата кнопка мыши на перемешаемом объекте. Выполняется для объекта, для которого начато перемещение
- DD.stop - кнопка мыши отжата, перемешение окончено
- DD.init - необязательный метод, используется для назначения обработки перемешения всем объектам класса 'drag'
Использованны общие универсальные функции:
// получить объект по его ID
function getObj(objID)
{
if (document.getElementById) {return document.getElementById(objID);}
else if (document.all) {return document.all[objID];}
else if (document.layers) {return document.layers[objID];}
}
// получить объект, в котором возникло событие
function getEventTarget(e) {
var e = e || window.event;
var target=e.target || e.srcElement;
if(typeof target == "undefined")return e; // передали this, а не event
if (target.nodeType==3) target=target.parentNode;// боремся с Safari
return target;
}
// назначить обработчик события
function addEvent(elm, evType, fn, useCapture) {
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;}
else if (elm.attachEvent) {
var r = elm.attachEvent('on' + evType, fn);
return r;}
else elm['on' + evType] = fn;
}
// удалить обработчик события
function removeEvent(elem, eventType, handler)
{
return (elem.detachEvent ? elem.detachEvent("on" + eventType, handler) :
((elem.removeEventListener) ? elem.removeEventListener(eventType, handler, false) : null));
}
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp(\"(^|\\s)\"+searchClass+\"(\\s|$)\");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
.
Прокомментировать/Отблагодарить