Please login or register. Welcome to the Studio, guest!


Quick Links:


newBookmarkLockedFalling

Eric

Eric Avatar



1,442


November 2005
// addEvent && removeEvent from quirksmode.org
function addEvent(obj,evt,fn) {
if (obj.addEventListener)
obj.addEventListener(evt,fn,false);
else if (obj.attachEvent)
obj.attachEvent('on'+evt,fn);
}

function removeEvent(obj,evt,fn) {
if (obj.removeEventListener)
obj.removeEventListener(evt,fn,false);
else if (obj.detachEvent)
obj.detachEvent('on'+evt,fn);
}

function addClass(el, klass)
{
if(!hasClass(el, klass))
{
var classes = el.className.split(' ');
classes.push(klass);
el.className = classes.join(' ');
}
}
function removeClass(el, klass)
{
var classes = el.className.split(' ');
for(var i = 0; i < classes.length; i++)
{
if(classes == klass)
{
classes.splice(i, 1);
break;
}
}
el.className = classes.join(' ');
}
function hasClass(el, klass)
{
var classes = el.className.split(' ');
for(var i = 0; i < classes.length; i++)
{
if(classes == klass)
{
return true;
}
}
return false;
}


function Draggable(el, events, handler)
{
this.element = el;
this.handler = handler || el;
addClass(this.handler, 'draggable');
this.handler.dragger = this;
this.handler.onmousedown = this.dragStart;
this.events = events;
this.start, this.mouseStart, this.current;
}
Draggable.current;
Draggable.prototype = {
'getMousePos': function(e)
{
if(!e) e = window.event;
var x = e.clientX;
var y = e.clientY;
return {'x': x, 'y': y};
},
'getOffsets': function(el)
{
el = el || this.element;
return {'x': el.offsetLeft, 'y': el.offsetTop};
},
'getAbsOffsets': function(el)
{
el = el || this.element;
var offs = this.getOffsets(el);
if(el.offsetParent)
{
var par = this.getAbsOffsets(el.offsetParent);
offs.x += par.x;
offs.y += par.y;
}
return offs;
},
'setPosition': function(x, y)
{
this.current = {'x': x, 'y': y};
this.element.style.left = x + this.start.x + 'px';
this.element.style.top = y + this.start.y + 'px';
},
'setStart': function(x, y)
{
x = (x)? x : 0;
y = (y)? y : 0;
this.start = {'x': x, 'y': y};
},
'dragStart': function(e)
{
var drg = this.dragger;

drg.trigger('preDragStart');

Draggable.current = drg;
drg.mouseStart = drg.getMousePos(e);
var abs = drg.getAbsOffsets();
drg.setStart(abs.x - drg.mouseStart.x, abs.y - drg.mouseStart.y);
document.body.appendChild(drg.element.parentNode.removeChild(drg.element));
drg.setPosition(drg.mouseStart.x, drg.mouseStart.y);
drg.element.style.position = 'absolute';

addEvent(document.body, 'mousemove', drg.dragMove);
addEvent(document.body, 'mouseup', drg.dragEnd);

drg.trigger('postDragStart');
return false;
},
'dragMove': function(e)
{
var drg = Draggable.current;
drg.trigger('preDragMove');

var curMouse = drg.getMousePos(e);
drg.setPosition(curMouse.x, curMouse.y)

drg.trigger('postDragMove');
},
'dragEnd': function(e)
{
var drg = Draggable.current;
drg.trigger('preDragEnd');

removeEvent(document.body, 'mousemove', drg.dragMove);
removeEvent(document.body, 'mouseup', drg.dragEnd);

Draggable.current = null;

drg.trigger('postDragEnd');
},
'trigger': function(event)
{
if(this.events[event])
{
if(this.events[event].constructor == Array)
{
for(var i = 0; i < this.events[event].length; i++)
{
this.events[event].call(this);
}
}
else
{
this.events[event].call(this);
}
}
}
};
[/size]



I'll pos some pre-built event things later, as that's where most of the functionality in a drag-drop comes from.


Last Edit: Jul 24, 2009 5:41:16 GMT by Eric

Chris

Chris Avatar

******
Head Coder

19,519


June 2005
:P Looks simple enough. I'm liking the way you set up the pre/post drag stuff. Reminds me of how a plugin system works for, well, most open source PHP apps. Which I guess is the logical way.

Eric

Eric Avatar



1,442


November 2005
Basic event object that increases functionality by a ton:
var dropHolders = {
'preDragStart': function()
{
this.originalHolder = this.element.parentNode;
},
'postDragEnd': function()
{
var drops = document.getElementsByTagName('div');
var oH = this.originalHolder;
delete this.originalHolder;
var offs, ch, c;
this.element.style.position = 'relative';
this.element.style.top = '0px';
this.element.style.left = '0px';
for(var d = 0; d < drops.length; d++)
{
if(hasClass(drops[d], 'droppable'))
{
offs = this.getAbsOffsets(drops[d]);
offs.x2 = offs.x + drops[d].offsetWidth;
offs.y2 = offs.y + drops[d].offsetHeight;
if(this.current.x > offs.x && this.current.x < offs.x2 &&
this.current.y > offs.y && this.current.y < offs.y2)
{
ch = drops[d].childNodes;
for(c = 0; c < ch.length; c++)
{
if(ch[c].nodeName == 'DIV' &&
this.getAbsOffsets(ch[c]).y > this.current.y)
{
this.element.parentNode.removeChild(this.element);
drops[d].insertBefore(this.element, ch[c]);
return;
}
}
this.element.parentNode.removeChild(this.element);
drops[d].appendChild(this.element);
return;
}
}
}
this.element.parentNode.removeChild(this.element);
oH.appendChild(this.element);
}
};


Example behavior:
digishout.com/digitalcs/tests/dragndrop.htm


Last Edit: Jul 24, 2009 5:29:29 GMT by Eric

Michael

Michael Avatar
*Has a custom title*



1,462


October 2007
Hm ... wonder if I can incorporate this into some drag/drop category sorter! :D

Eric

Eric Avatar



1,442


November 2005
Michael Avatar
Hm ... wonder if I can incorporate this into some drag/drop category sorter! :D

I've used a more complex event script to manage complex hierarchies of software dependencies and key generation. Every drag and drop had to change several hidden field values so that they could be posted. It definitely can be done.

Chris

Chris Avatar

******
Head Coder

19,519


June 2005
Eric, can I kill the pre there? It's stretching v1 horribly.

Eric

Eric Avatar



1,442


November 2005
Chris Avatar
Eric, can I kill the pre there? It's stretching v1 horribly.
Negative :P, then it's not human readable. Is that better?

Btw, I'm using V1 and it wasn't that bad for me.

Chris

Chris Avatar

******
Head Coder

19,519


June 2005
It's better now. :P It was bad if you don't use the post splitter (having a hash in the URL disables it.)

Josh

Josh Avatar
Where were you when Reach fell?

******
Legendary Studio Member

4,806


May 2008
Not gonna lie... that seems like a shitload of code for something that seems so simple. Granted... I know nothing about coding but still. lol

Fredy Sucks Donkey Ass. Big. Donkey. Ass.

Eric

Eric Avatar



1,442


November 2005
Josh Avatar
Not gonna lie... that seems like a shitload of code for something that seems so simple. Granted... I know nothing about coding but still. lol

Fredy Sucks Donkey Ass. Big. Donkey. Ass.
Yeah it is fairly lengthy, but that's the price you pay for generic code versus target specific code.

Chris

Chris Avatar

******
Head Coder

19,519


June 2005
Josh Avatar
Not gonna lie... that seems like a shitload of code for something that seems so simple. Granted... I know nothing about coding but still. lol

Fredy Sucks Donkey Ass. Big. Donkey. Ass.


Pretty much, Eric's thing above is much more efficient and adaptable. :P It's like a JS library... I could use an entire library to add a div to the page, or I could add a single line. For reusability purposes, I want the library. If it's very specific, then the single line.


Last Edit: Aug 3, 2009 4:31:31 GMT by Chris

~Memzak~

~Memzak~ Avatar
Inquire never, so always need elephants.

****
Senior Member

408


May 2009
I didn't realize what this did when I first saw it.... but now I know...

This could be turned into a new way of reorganising catagories and boards....




newBookmarkLockedFalling