вот код , может тут понятней будет
var _shift = {}; //смещение мыши относительно элемента по X и по Y var drag_prop = {};//свойства перемещаемого обьекта var drag = { status: false, init:function(){ var elem_for_drag, i, n; elem_for_drag = querySelector.All('draggable'); i = elem_for_drag.length; while(i--){ n = elem_for_drag[i]; Event.addListener(n, "mousedown", drag.down_mouse, false); Event.addListener(n, "dragstart", drag.drag_s, false); } }, down_mouse: function (e) { action.down.call(this,e); }, drag_s: function (e){ if(e.preventDefault){ e.preventDefault(); } else{ event.returnValue = false }; } }; var _avatar = { create: function(elem){ var width, height, avatar; avatar = document.createElement("div"); avatar.style.width = elem.offsetWidth + "px"; avatar.style.height = elem.offsetHeight + "px"; avatar.className = "avatar"; document.body.appendChild(avatar); return avatar; } }; var drop = { lastElem: false, state_original: false, end : false }; var action = { count: 0 , auto: false, down : function(evt){ var target, e; e = evt || event; which = e.which || e.button; target = e.target || e.srcElement; if(which != 1) return false; drag.obj = this || target; drag_prop.pageX = mouse.pageX(e); drag_prop.pageY = mouse.pageY(e); drag_prop.posX = Obj.positX(drag.obj); drag_prop.posY = Obj.positY(drag.obj); _shift.X = drag_prop.pageX - drag_prop.posX; _shift.Y = drag_prop.pageY - drag_prop.posY; Event.addListener(document,"mousemove",action.move_wrap,false); Event.addListener(document,"mouseup",action.up,false); }, move_wrap: function (e){ setTimeout(function(){ action.move(e); },20); }, move: function (e){ var shift_elX, shift_elY, avatar, target; var pageX, pageY, drop_el; pageX = mouse.pageX(e); pageY = mouse.pageY(e); if(!drag.status) { shift_elX = pageX - _shift.X - drag_prop.posX; shift_elY = pageY - _shift.Y - drag_prop.posY; if(Math.abs(shift_elY) < 3 || Math.abs(shift_elX) < 3)return; drag.avatar = _avatar.create(drag.obj); cls.addClass(drag.obj, "drag_obj"); drag.status = true; } if(param.move_drop){ drag.avatar.style.display = "none"; drop_el = action.serchAttr_drop(pageX, pageY); if(drop_el){ move_drop.call(drop_el, drag.avatar);//функция измений drop блока , когда элементы над ним drop.lastElem = drop_el ; drop.state_original = true; } if(!drop_el && drop.state_original){ drop_out.call(drop.lastElem, drag.avatar);//функция отката измений после ухода курсора с drop блока drop.state_original = false; } drag.avatar.style.display = ''; } drag.avatar.style.left = pageX - _shift.X +"px"; drag.avatar.style.top = pageY - _shift.Y +"px"; }, up : function(evt){ var last_posX, last_posY, drop_elem, span, e; if(drag.avatar){ e = evt || event; Event.removeListener(document,"mousemove", action.move_wrap,false); Event.removeListener(document,"mouseup", action.move,false); if(drop.lastElem){ drop_out.call(drop.lastElem, drag.avatar); } cls.removeClass(drag.obj, "drag_obj"); last_posX = e.clientX; last_posY = e.clientY; console.log(drag.avatar); drag.avatar.parentNode.removeChild(drag.avatar); drag.avatar = false; drag.status = false; drop_elem = action.serchAttr_drop(last_posX,last_posY); if(drop_elem){ action.count++; elemnt_drop.call(drag.obj, drop_elem); if(action.auto != "stop" && param.auto_size) action.width_height(drop_elem); } } }, width_height:function( drop_elem){ var width_drop, height_drop, height, width, height_drag, width_drag; width_drop = drop_elem.offsetWidth; height_drop = drop_elem.offsetHeight; width_drag = drag.obj.offsetWidth + parseInt(getComputed(drag.obj).marginLeft); width_drag += parseInt(getComputed(drag.obj).marginRight); height_drag = drag.obj.offsetHeight + parseInt(getComputed(drag.obj).marginTop); height_drag += parseInt(getComputed(drag.obj).marginBottom); width = width_drop - width_drag * action.count; height = height_drop - height_drag ; if( width_drag > width_drop){ drop_elem.style.width = width_drag+"px"; } if(width < width_drag && height < height_drag) action.auto = true; if(action.auto){ drop_elem.style.height = "auto"; action.auto = "stop"; } }, serchAttr_drop: function(x,y){ var drop_elem = document.elementFromPoint(x, y); while(drop_elem != document && drop_elem.getAttribute("droppable") == null){ drop_elem = drop_elem.parentNode; } return drop_elem === document ? null : drop_elem; } }; |
Цитата:
|
допустим есть дерево из дом элементов и его нужно перетащить, что бы не таскать все дерево по странице я делаю его клон (беру его ширину и высота и создаю div),
и суть не в этой прозрачной фигне (я пока экспериментирую :) ), суть в том почему она застряет с Timeout на месте а без него все ок? |
Цитата:
в <img date="obj[N]" (восстанавливаю по необходимости) |
Цитата:
короче алгоритм такой: -нажимаеш кнопку мыши если начал движение появляется прозрачная иконка - елмент выделяются тенью и margin , создается иконка которая находится под курсором - если mouseup над блоком с атрибутом droppable то элемент по котрому кликнули перенесется туда.. -если нет то иконка исчезнет не совсем похоже на алгоритм , но как то так=) |
cyber,
Тады так 1. вычисляем сразу все размеры элементов и ставим над ними полупрозрачные c тенью div cо ссылками(id, класс, или индекс) на сам элемент плюс начальные координаты ( data="id, начальные координаты") - div делаем visibility hidden, при наведении на скрытый div он теряет прозрачность и мы его тащим в корзину - если дотащили - он по ссылке перетягивает и исходник ... - ежли нет - возвращается по запомненным координатам (второй параметр в data) ??? |
у меня уже есть полностью готовый скрипт, мне не нужен алгоритм=)
тут http://cyberua.16mb.com/notTimeout/ но когда я его изменяю меняю Event.addListener(document,"mousemove",action.move,false); на Event.addListener(document,"mousemove",action.move_wrap,false); метод move_wrap move_wrap: function (e){ setTimeout(function(){ action.move(e); },20); } вызывает тоже функцию только с задержкой и после добавление задержки начинаются глюки при mouseup Event.removeListener(document,"mousemove", action.move_wrap,false); Event.removeListener(document,"mouseup", action.move,false); if(drop.lastElem){ drop_out.call(drop.lastElem, drag.avatar); } cls.removeClass(drag.obj, "drag_obj");// не срабатывает last_posX = e.clientX; last_posY = e.clientY; drag.avatar.parentNode.removeChild(drag.avatar);// не срабатывает drag.avatar = false; drag.status = false; drop_elem = action.serchAttr_drop(last_posX,last_posY); if(drop_elem){ action.count++; elemnt_drop.call(drag.obj, drop_elem); if(action.auto != "stop" && param.auto_size) action.width_height(drop_elem); } } } и самое странное в консоле нет ошибок, такое чувство что их тупо перепрыгивает.... тут с Timeout http://cyberua.16mb.com/drag&drop/ |
cyber,
ясн ... :-? готовый алгоритм - скучно(и длинный он больно) ... прост тут вродь ваще кодов почти нет Если поставить события в этих полупрозрачных div, которые и вызывают функции <div class=Drag onmousedown="Yes(this)" onmousemove="Funk1(this)" onmouseout="Funk2(this)" data="IDисходника, X0,Y0"></div> функции всего три 1.Yes(this) Разрешаем обработку onmousemove присваиваем Доп.класс vidible для видимости 2. Funk1(this) отслеживаем мышь и перемещаем объект при наличии наличии onmousedown 3. Funk2(this) - удаляем класс vidible - принимаем решение: перетаскивать объект или возвращаемcz на исходную скрытие и показ полупрозрачных div - css |
ну почему длинный?
var _shift = {}; //смещение мыши относительно элемента по X и по Y var drag_prop = {};//свойства перемещаемого обьекта var drag = { status: false, init:function(){ var elem_for_drag, i, n; elem_for_drag = querySelector.All('draggable'); i = elem_for_drag.length; while(i--){ n = elem_for_drag[i]; Event.addListener(n, "mousedown", drag.down_mouse, false); Event.addListener(n, "dragstart", drag.drag_s, false); } }, down_mouse: function (e) { action.down.call(this,e); }, drag_s: function (e){ if(e.preventDefault){ e.preventDefault(); } else{ event.returnValue = false }; } }; var _avatar = { create: function(elem){ var width, height, avatar; avatar = document.createElement("div"); avatar.style.width = elem.offsetWidth + "px"; avatar.style.height = elem.offsetHeight + "px"; avatar.className = "avatar"; document.body.appendChild(avatar); return avatar; } }; var drop = { lastElem: false, state_original: false, end : false }; var action = { count: 0 , auto: false, down : function(evt){ var target, e; e = evt || event; which = e.which || e.button; target = e.target || e.srcElement; if(which != 1) return false; drag.obj = this || target; drag_prop.pageX = mouse.pageX(e); drag_prop.pageY = mouse.pageY(e); drag_prop.posX = Obj.positX(drag.obj); drag_prop.posY = Obj.positY(drag.obj); _shift.X = drag_prop.pageX - drag_prop.posX; _shift.Y = drag_prop.pageY - drag_prop.posY; Event.addListener(document,"mousemove",action.move,false); Event.addListener(document,"mouseup",action.up,false); }, move_wrap: function (e){ setTimeout(function(){ action.move(e); },20); }, move: function (e){ var shift_elX, shift_elY, avatar, target; var pageX, pageY, drop_el; pageX = mouse.pageX(e); pageY = mouse.pageY(e); if(!drag.status) { shift_elX = pageX - _shift.X - drag_prop.posX; shift_elY = pageY - _shift.Y - drag_prop.posY; if(Math.abs(shift_elY) < 3 || Math.abs(shift_elX) < 3)return; drag.avatar = _avatar.create(drag.obj); cls.addClass(drag.obj, "drag_obj"); drag.status = true; } //определение над блоком или нет if(param.move_drop){ drag.avatar.style.display = "none"; drop_el = action.serchAttr_drop(pageX, pageY); if(drop_el){ move_drop.call(drop_el, drag.avatar);//функция измений drop блока , когда элементы над ним drop.lastElem = drop_el ; drop.state_original = true; } if(!drop_el && drop.state_original){ drop_out.call(drop.lastElem, drag.avatar);//функция отката измений после ухода курсора с drop блока drop.state_original = false; } drag.avatar.style.display = ''; } //------------------------------------- drag.avatar.style.left = pageX - _shift.X +"px"; drag.avatar.style.top = pageY - _shift.Y +"px"; }, up : function(evt){ var last_posX, last_posY, drop_elem, span, e; if(drag.avatar){ e = evt || event; Event.removeListener(document,"mousemove", action.move,false); Event.removeListener(document,"mouseup", action.move,false); if(drop.lastElem){ drop_out.call(drop.lastElem, drag.avatar); } cls.removeClass(drag.obj, "drag_obj"); last_posX = e.clientX; last_posY = e.clientY; drag.avatar.parentNode.removeChild(drag.avatar); drag.avatar = false; drag.status = false; drop_elem = action.serchAttr_drop(last_posX,last_posY); if(drop_elem){ action.count++; elemnt_drop.call(drag.obj, drop_elem); if(action.auto != "stop" && param.auto_size) action.width_height(drop_elem); } } }, //получилась большой функция для измени я размера drop блока width_height:function( drop_elem){ var width_drop, height_drop, height, width, height_drag, width_drag; width_drop = drop_elem.offsetWidth; height_drop = drop_elem.offsetHeight; width_drag = drag.obj.offsetWidth + parseInt(getComputed(drag.obj).marginLeft); width_drag += parseInt(getComputed(drag.obj).marginRight); height_drag = drag.obj.offsetHeight + parseInt(getComputed(drag.obj).marginTop); height_drag += parseInt(getComputed(drag.obj).marginBottom); width = width_drop - width_drag * action.count; height = height_drop - height_drag ; if( width_drag > width_drop){ drop_elem.style.width = width_drag+"px"; } if(width < width_drag && height < height_drag) action.auto = true; if(action.auto){ drop_elem.style.height = "auto"; action.auto = "stop"; } }, //--------------------------------------------------- // еще не маленький метод для проверки не стоит ли атрибут droppable у родителя serchAttr_drop: function(x,y){ var drop_elem = document.elementFromPoint(x, y); while(drop_elem != document && drop_elem.getAttribute("droppable") == null){ drop_elem = drop_elem.parentNode; } return drop_elem === document ? null : drop_elem; } }; если это убрать получится обычный простейший drag and drop var _shift = {}; //смещение мыши относительно элемента по X и по Y var drag_prop = {};//свойства перемещаемого обьекта var drag = { status: false, init:function(){ var elem_for_drag, i, n; elem_for_drag = querySelector.All('draggable'); i = elem_for_drag.length; while(i--){ n = elem_for_drag[i]; Event.addListener(n, "mousedown", drag.down_mouse, false); Event.addListener(n, "dragstart", drag.drag_s, false); } }, down_mouse: function (e) { action.down.call(this,e); }, drag_s: function (e){ if(e.preventDefault){ e.preventDefault(); } else{ event.returnValue = false }; } }; var action = { count: 0 , auto: false, down : function(evt){ var target, e; e = evt || event; which = e.which || e.button; target = e.target || e.srcElement; if(which != 1) return false; drag.obj = this || target; drag_prop.pageX = mouse.pageX(e); drag_prop.pageY = mouse.pageY(e); drag_prop.posX = Obj.positX(drag.obj); drag_prop.posY = Obj.positY(drag.obj); _shift.X = drag_prop.pageX - drag_prop.posX; _shift.Y = drag_prop.pageY - drag_prop.posY; Event.addListener(document,"mousemove",action.move,false); Event.addListener(document,"mouseup",action.up,false); }, move_wrap: function (e){ setTimeout(function(){ action.move(e); },20); }, move: function (e){ var shift_elX, shift_elY, avatar, target; var pageX, pageY, drop_el; pageX = mouse.pageX(e); pageY = mouse.pageY(e); if(!drag.status) { shift_elX = pageX - _shift.X - drag_prop.posX; shift_elY = pageY - _shift.Y - drag_prop.posY; if(Math.abs(shift_elY) < 3 || Math.abs(shift_elX) < 3)return; drag.avatar = _avatar.create(drag.obj); cls.addClass(drag.obj, "drag_obj"); drag.status = true; } drag.avatar.style.left = pageX - _shift.X +"px"; drag.avatar.style.top = pageY - _shift.Y +"px"; }, up : function(evt){ var last_posX, last_posY, drop_elem, span, e; if(drag.avatar){ e = evt || event; Event.removeListener(document,"mousemove", action.move,false); Event.removeListener(document,"mouseup", action.move,false); if(drop.lastElem){ drop_out.call(drop.lastElem, drag.avatar); } cls.removeClass(drag.obj, "drag_obj"); last_posX = e.clientX; last_posY = e.clientY; drag.avatar.parentNode.removeChild(drag.avatar); drag.avatar = false; drag.status = false; drop_elem = action.serchAttr_drop(last_posX,last_posY); if(drop_elem){ action.count++; elemnt_drop.call(drag.obj, drop_elem); } } }, }; |
я не вижу смысла в лишних операциях с дом что бы все элементам сверху налаживать div зачем это делать если элемент вполне возможно не будут трогать...
чем меньше операций над DOM тем лучше=) создание иконки простейшие create: function(elem){ var width, height, avatar; avatar = document.createElement("div"); avatar.style.width = elem.offsetWidth + "px"; avatar.style.height = elem.offsetHeight + "px"; avatar.className = "avatar"; document.body.appendChild(avatar); return avatar; } |
Часовой пояс GMT +3, время: 04:47. |