ешкин кот, думал про querySelectorAll но не знал как искать по атрибуту .спасибо :thanks:
долго думал насчет старых ие и решил что буду писать для ие 8+ |
Цитата:
|
Цитата:
Цитата:
или все таки сделать в общем скрипт работает в старых ие даже в 6... все таки можно написать кросбраузерно=)
function (selector){
var query , n, arr_Qery = [];
query = document.querySelectorAll("["+selector+"]");
if(query){
return query;
}
query = document.body.getElementsByTagName('*');
for(var i = query.length;i--;){
n = query[i];
if(n.getAttribute(selector) !== null){
arr_Qery.push(n);
}
}
return arr_Qery;
}
|
и последний вопрос который остался
почему не работает
addEventListener("dragstart", drag.drag_s, false);
и можно переходить к хтмл 5 части=) |
Цитата:
Цитата:
|
знаю конечно , немного затупил с методом drag.drag_s
нужно было так
drag_s: function (e){
if(e.preventDefault){
e.preventDefault();
} else {
event.returnValue = false
}
}
а у меня было так
drag_s: function (){
return false;
}
|
а да забыл=)
был вопрос еще по оптимизации=) но как только найду почему перестало работать в старых браузерах залью наглядный пример=) |
вот страница http://cyberua.16mb.com/drag&drop/
в чем проблема
Event.addListener(document,"mousemove",action.move_wrap,false);
move_wrap: function (e){
setTimeout(function(){
action.move(e);
},20);
}
когда добавляю задержку в 20мс, если резко дернуть переместить элемент то он не исчезает , событие mouseup срабатывает |
Чот ток посмотрел тему сток кода... ужс
В принципе -css при наведении на элемент сss делаем позицию absolute; по onmousedown="TestMoiseOffset(this)" тестируем позицию курсора и смещаем за ним По onmouseout="JamToWat()" - прыгаем туды иль сюды Почему то тащица какая то полупрозрачка вместо товара - потом ток прыгает товар... (Но я возможно прост не в теме - ... :) |
Цитата:
если этот квадратик отпустить над 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 _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;
}
|
так поможеш разобратся почему его плющит из за Timeout?
Не против если на ты буду?) |
cyber,
Oки попробую , ток я засыпаю уже, |
я тоже))
Ушел спать)) Спс зарание)) |
Цитата:
2. А есть ли они ? Часто используемые и востребованные Варианты фреймворка, когда перемещаемых элементов более 100 ? 3. Метода позволяет, без увеличения кода, возвращать товар из корзины(ну не понравилось!) |
Цитата:
|
cyber,
Не наю - тут у тьву достаточно веский аргумент многовложенного объекта (хотя такой, кроме гугол карты - не наю - тут думайте о реальности сами) я про создание заранее, по загрузке страницы надобъектных div - в основном использовании их будет немного) ============================================== я всё про это (если не надоел... Цитата:
|
я не хочу использовать такой метод потому что для каждого элемента прийдется прочитывать позицию ,и налаживать div что как по мне является лишним..
но это не главная проблема, пока я не пойму почему начинает тормозить при добавление Timeout, все остальное на заднем плане.. |
cyber,
можно кнешн и динамически - но добавит жа еще три - четыре функции - стоит ли борьба усложнений ? просчет позиции и размеров 7 операций создание объекта и удаление больше (посколь к нему и это доплюсовываецо и просчет позиций |
какие 3-4 всего один метод=)
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;
}
};
и все=) я пришел к выводу что создавать div после начала движение элемента выгодней потому что если создавать div для всех элементов сразу больше нагружает чем когда при смещение между созданием div проходит где то 1 сек(и то если быстро перемещать, так что преимущество есть) . идею с иконкой позаимствовал у iGoogle=) |
cyber,
Цитата:
|
там все равно стили пройдется подключать, поэтому проще через class=)
|
:help: сделал без иконки , перетаскивание самого элемента и все равно проблема с Timeout
|
cyber,
:) А слабо упростить функции добавив к объекту onmousedown="Yes(this)" onmousemove="Funk1(this)" onmouseout="Funk2(this)" data(начальная позиция)="X0,Y0" |
вместо
while(i--){
n = elem_for_drag[i];
Event.addListener(n, "mousedown", drag.down_mouse, false);
Event.addListener(n, "dragstart", drag.drag_s, false);
}
сделать
while(i--){
n = elem_for_drag[i];
n.onmousedown = function (e){
}
n.onmousemove = function (e){
}
n.onmouseup = function(e){
}
}
если ты об этом , то этот способ в 9 раз медленнее того что выше |
|
cyber,
Пробуй в таймере определять отпущена ли нажатие мыши - тогда возвращайся в анализ позишен |
так?
move_wrap: function (e){
setTimeout(function(){
if(action.mouseup)return;
action.move(e);
},20);
},
up : function(evt){
...
action.mouseup = true;
....
}
|
блин, дошло=)
после mouseup походу опять таймер еще раз срабатывал=) |
все теперь готово=)
теперь буду писать html 5 drag and drop=) а потом сделаю проверку поддерживает браузер хтмл 5 drag and drop=) и совмещу оба скрипта=) |
setTimeout(function(){
action.move(e);},20);
При тайм-ауте событие e не передается-теряется |
| Часовой пояс GMT +3, время: 09:47. |