PDA

View Full Version : DHTML Dragging and Dropping...



pcbrainbuster
04-05-2007, 12:35 AM
Hello agian everyone :),

Again as always I have yet more questions... And this time as the title suggests is "how do I create a script that will allow drag on an object"...

mburt
04-05-2007, 12:46 AM
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Dom Drag/Drop</title>
<script type="text/javascript">
var ie = document.all;
var ns = document.getElementById && !ie;
function dragbyclass(e) {
var fobj = ns ? e.target : event.srcElement;
if (fobj.tagName=="DIV" && fobj.className=="drag") {
var ev=e||event;
var offsetx=ev.clientX-fobj.offsetLeft;
var offsety=ev.clientY-fobj.offsetTop;
document.onmousemove=function mousemove() {
fobj.style.left=ev.clientX-offsetx;
fobj.style.top=ev.clientY-offsety;
if (fobj.offsetLeft < 1) {
fobj.style.left = 1;
return false;
}
else if (fobj.offsetTop < 1) {
fobj.style.top = 1;
return false;
}
else if ((fobj.offsetTop + fobj.offsetHeight) > 706) {
fobj.style.top = 706;
return false;
}
else {document.onmousemove = mousemove;}
return false
}
fobj.onmouseup=function() {
document.onmousemove=null;
}
}
}
document.onmousedown=dragbyclass;
</script>
<style type="text/css">
.drag {
width:200px;
height:200px;
position:absolute;
border:1px solid black;
background:silver
}
</style>
</head>
<body>
<div class="drag" style="left:40px;top:60px;z-index:100">Drag number ONE</div>
<div class="drag" style="left:40px;top:60px">Drag number TWO</div>
</body>
</html>

pcbrainbuster
04-05-2007, 01:20 AM
Thanks Mike for your post but what I wanted was something I could relate to, though it is still ok I still understand it a little :)...

I might need to look at more examples over the internet to see how everyone does and find a more easier thing to relate to unless you give me a easier script :)

mburt
04-05-2007, 01:27 AM
There is no "easier script". Understanding javascript, is understanding javascript. You should be able to understand that, as it relies on basic principles. If not, you need to read up a good js tutorial.

pcbrainbuster
04-05-2007, 02:19 AM
No no thats not what I meant... What I ment was that since I am a begginer to this (drag) aspect of JavaScript, what you did was a little strong in that aspect...

But I simply understand what was going on (otherwise I can not call myself a JavaScripter, if I don't understand what I am doing)...

Well GoodNight from my end :)

shachi
04-05-2007, 08:46 AM
pcbrainbuster: As you want to create a dnd script, I think you should first understand the principals of basic dnd.

It goes as follows:



When the user clicks an object and moves his/her mouse around, move the object the mouse is clicking, which is done by:

var stupid = false;

document.onmousedown = function(){
// this block is triggered when the user clicks on the object
var stupid = true;
document.onmousemove = function(){
if(stupid == true){
// this block is triggered when the user's mouse is down and the mouse is moving, that is ... "dragging", the element's position will be the coordinates of the mouse position plus some simple mathematics
}
}
}

document.onmouseup = function(){
stupid = false;
}



I think that's the simplest it can get.:p

And that's that. Hope it helps. :)

mburt
04-05-2007, 10:06 AM
Again, simply the fundamentals of javascript. pcbrainbuster should look that up on the web, if he/she doesn't know what boolean values do and how they work.

shachi
04-05-2007, 11:20 AM
Yep, mike is completely right. If you don't get anything, go back to the basics. They will definitely help you.

pcbrainbuster
04-05-2007, 09:24 PM
Well I tried to maake my own drag script from what I learned from you two and here it is -

<html>
<head>
<style>
.drag {
position: relative;
border: 1px solid;
background-color: red;
color: yellow;
top: 5cm;
left: 5cm;
width: 2cm;
height: 2cm;}
</style>
</head>
<body bgcolor="black">
<div class="dragable" style="z-index:1" onmousedown="drags(this)">Shachi</div>
<div class="dragable" style="z-index:2" onmousedown="drags(this)">mburt</div>
<script>
var hold=0
function drags(item) {
hold=1
if (item.class=="dragable" && hold==1) {
item.style.offsetLeft=event.x-item.style.offsetLeft
item.style.offsetTop=event.y-item.style.offsetTop
document.onmousemove=function() {drags(item)}}
}

document.onmouseup=new function("hold=0")
</script>
</body>
</html>

Though there is a problem, the div turns invisible and ther eis nothing on the screen, mind helping me out? :) And FYI you lot misunderstood what I meant by I don't understand :)

Thanks :)

mburt
04-05-2007, 09:53 PM
The "class" attribute is always referred to as "className".
Also, you serverely messed up your attributes.

1) OFFSETLEFT/TOP IS NOT AN ATTRIBUTE WHICH CAN HAVE VALUES APPLIED TO IT
2) event.x/y should be event.clientX/Y
3) document.onmousemove is inside of drags(), so calling it again would create an unwanted loop.
4)You're neglecting the fact that event is IE only, use "e".


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>drag/drop</title>
<style type="text/css">
.dragable {
position: absolute;
border: 1px solid;
background-color: red;
background: yellow;
top: 5;
left: 5;
width:200px;height:200px;
}
</style>
<script type="text/javascript">
function drag(item,e) {
var ev = e||event;
if (item.className=="dragable") {
var offsetx = (ev.clientX-item.offsetLeft),offsety = (ev.clientY-item.offsetTop);
document.onmousemove=function() {
item.style.left=ev.clientX-offsetx;
item.style.top=ev.clientY-offsety;
}
document.onmouseup=function(){document.onmousemove=null;}
}
}
</script>
</head>
<body bgcolor="black">
<div class="dragable" style="z-index:1" onmousedown="drag(this)">Shachi</div>
<div class="dragable" style="z-index:2;top:300px;" onmousedown="drag(this)">mburt</div>
</body>
</html>
:)

Sorry for the outburst, but you are extremely annoying in the fact that you don't what attributes do what.

pcbrainbuster
04-05-2007, 10:11 PM
Well I do understand what attributes do what its just that in this case I never knew that class was className and don't understand what you mean by e...

Also event.clientX/Y is the same as event.x/y...

Anyway since you barely edited my version of the script I know understand how to make drag scripts :),

Thanks :)

mburt
04-05-2007, 10:14 PM
Also event.clientX/Y is the same as event.x/y...

No it's not. Either only works in INTERNET EXPLORER, and should be shot.
In my example you see the argument "e" in the function, further called in the variable "ev" as "ev || event" which defines "ev" for anything besides Internet Explorer, and event which acts for IE.


Anyway since you barely edited my version of the script I know understand how to make drag scripts ,

I put in an important feature:

var offsetx = (ev.clientX-item.offsetLeft),offsety = (ev.clientY-item.offsetTop);

You didn't have that, and I doubt you understand what it does. Would you care to elaborate?

pcbrainbuster
04-05-2007, 10:29 PM
Sure :mad:,

That line of code has two variables in one seperated by the comma, the first part in brackets calculates the offsetleft of the total position by taking away the objects left offset from the mouse's offset left and so does the other side (except its offsetTop)...

How's that for elaboration :)... (I'm only making these mistakes cause of how tired I am (these days since I have Easter Holidays from school I tend to stay awake till late at night, this obvioulsy seeing as how I wake up early and sleep late makes me very tired by this time of day...))

edit//- And when I said that "anyway since you barely edited my version of the script I know understand how to make drag scripts" I was referring to my original script...

mburt
04-06-2007, 03:10 AM
Your script didn't work, mine did. There's a big difference in just "size".
Showing your anger won't give you much of a reputation around here either.

pcbrainbuster
04-06-2007, 02:16 PM
I wasn't angry :), like I said before in some thread, I like using icons :)...

And I don't mind admitting your a WAY better coder then me to :)... It's all a matter of time...

Besides I like thinking of you as a friend and not a enemy :)...

mburt
04-06-2007, 02:19 PM
I wasn't angry , like I said before in some thread, I like using icons
..Heh. I can see. Just don't misuse the emoticons.

pcbrainbuster
04-06-2007, 02:22 PM
Well what can I say, I'm addicted :)

edit// - Well thanks for the code, check ot thses sites and challenge yourself :) -

http://www.walterzorn.com/dragdrop/dragdrop_e.htm
http://tool-man.org/examples/edit-in-place.html

Man i'm very sorry but theres a problem... -

<html>
<body>
<div id="dragable" onmousedown="stard(this)" style="position: absolute; height: 100px; width: 100px; border: 1px solid; top: 5cm; left: 5cm;">PcBrainBuster</div>
<script>
function stard(item) {
document.onmousemove = function() {
item.style.left = event.clientX-(event.clientX-item.offsetLeft)
item.style.top = event.clientY-(event.clientY-item.offsetTop)}
document.onmouseup = function() {document.onmousemove=null}
}
</script>
</body>
</html>

Theres really only one problem that i've detected but and it seems that its the positioning area in the script... Very sorry for the whole hassly as usual but hey...

riptide
04-06-2007, 07:01 PM
No it's not. Either only works in INTERNET EXPLORER, and should be shot.
In my example you see the argument "e" in the function, further called in the variable "ev" as "ev || event" which defines "ev" for anything besides Internet Explorer, and event which acts for IE.



I put in an important feature:

var offsetx = (ev.clientX-item.offsetLeft),offsety = (ev.clientY-item.offsetTop);

You didn't have that, and I doubt you understand what it does. Would you care to elaborate?

heay I never understood the e thing I mean it never worked when I coded with it can you use R or something else, does it have to be an e

mburt
04-06-2007, 07:15 PM
e is the reference point for firefox to calls it's window events. Any other letter won't work.

riptide
04-06-2007, 07:24 PM
but e works in all browsers? how do you set it up do you have to define it.

I saw a script that use e to find out which link was clicked. If that is true could you use that with switch with lots of links. Right now I'm trying to find out if I could use a getElementsByClassName function to get the right links.

pcbrainbuster
04-06-2007, 07:28 PM
No it dosn't you need to use event in IE, I don't know about others... And please just make your own thread on e...

mburt
04-06-2007, 07:31 PM
Wow... you said something useful (just kidding :p).

As for the links...

onload=function() {
for (var i=0,t=document.getElementsByTagName("*");i < t.length;i++) {
if (t[i].className == "MyClassName") {
//do something
}
}
}

Twey
04-06-2007, 07:37 PM
t=document.getElementsByTagName("*");This doesn't work in some or all versions of IE, in which you have to use document.all instead:
t=document.getElementsByTagName("*")||document.all;

mburt
04-06-2007, 07:57 PM
Point taken. Testing in IE 6... It seems to work fine.

pcbrainbuster
04-06-2007, 08:02 PM
You lost me :(, I understand what is going on in that code but don't understand what that has to do with my code ... For now just base your code in on the div...

But why doesn't the code I posted last work :confused:...

Twey
04-06-2007, 08:09 PM
e is the reference point for firefox to calls it's window events. Any other letter won't work.It's not a magic letter, it's just the first argument passed to the event handler function. You can reference it as arguments[0] if you want.

mburt
04-06-2007, 08:45 PM
It's not a magic letter, it's just the first argument passed to the event handler function. You can reference it as arguments[0] if you want.
It has to be called globally though doesn't it? And if the function has more then one argument it won't work either.

document.oncontextmenu = menu;
would work, but

document.oncontextmenu = function() {menu();}
wouldn't?

Twey
04-06-2007, 09:30 PM
It has to be called globally though doesn't it?Hm? No, the function is called by the engine as a property of the element to which it is attached.

document.oncontextmenu = menu;would work, but
document.oncontextmenu = function() {menu();}wouldn't?No, because the two aren't equivalent (presuming the oncontextmenu event gets an event object; I don't use it, so I'm not sure if it does). If you want them to be equivalent, the latter would be:
document.oncontextmenu = function(a) { menu(a); };or, more precisely,
document.oncontextmenu = function() {
menu.apply(
this,
Array.prototype.slice.apply(arguments)
);
};

mburt
04-06-2007, 09:47 PM
You're a prototype junkie... :p
Also, (offtopic) howcome:

Object.prototype.erase = function() {while (this.firstChild) this.removeChild(this.firstChild);}
Doesn't work? Is Object a valid prototype keyword?

Twey
04-06-2007, 09:56 PM
Is Object a valid prototype keyword?Yes. That will work in most browsers (not that you should do it anyway), but not IE. In IE, DOM objects are "special:" they have no constructor function, aren't considered part of the JScript environment, and really just don't play nicely with the rest of JScript. You can't extend them or work with them as you can with other objects.

In other browsers, this will work, but it shouldn't be used. Extending a constructor is for use with functions and properties that apply to every possible instance. For example, pad() can be added to Number because all Number instances can safely be pad()ed, and it makes sense to do so. All Object instances are not DOM nodes, so Object should not be extended with methods for working with DOM nodes. In fact, there are very few methods that can be said to apply to all possible objects, so extending Object at all is usually a sign that you're doing something wrong. Environments that do support extending DOM nodes usually provide a special constructor to do so, such as Gecko's HTMLElement and derived constructors (HTMLParagraphElement, HTMLSpanElement, HTMLDivElement, HTMLBodyElement, HTMLHtmlElement...).

mburt
04-06-2007, 10:05 PM
Yes. That will work in most browsers (not that you should do it anyway), but not IE. In IE, DOM objects are "special:" they have no constructor function, aren't considered part of the JScript environment, and really just don't play nicely with the rest of JScript. You can't extend them or work with them as you can with other objects.

In other browsers, this will work, but it shouldn't be used. Extending a constructor is for use with functions and properties that apply to every possible instance. For example, pad() can be added to Number because all Number instances can safely be pad()ed, and it makes sense to do so. All Object instances are not DOM nodes, so Object should not be extended with methods for working with DOM nodes. In fact, there are very few methods that can be said to apply to all possible objects, so extending Object at all is usually a sign that you're doing something wrong. Environments that do support extending DOM nodes usually provide a special constructor to do so, such as Gecko's HTMLElement and derived constructors (HTMLParagraphElement, HTMLSpanElement, HTMLDivElement, HTMLBodyElement, HTMLHtmlElement...).

So adding a function to a String, Array, Number will be safe because they always have the same properties. Right.

A logical way to add a property to an object might be to:

window.onload=function() {
for (var i=0,t=document.getElementsByTagName("*")||document.all;i<t.length;i++) t[i].attribute = "myAttribute";
}
Right?

mburt
04-06-2007, 10:14 PM
What do you want? Us to talk to you all night about your problems?

Twey
04-06-2007, 10:22 PM
A logical way to add a property to an object might be to:That's the only way to do it in IE, yes, but the effect isn't quite the same (any new elements added to the DOM after the page has been loaded, for example, will not have the new property).

mburt
04-06-2007, 10:30 PM
Yeah, I know, but that can be easily fixed by giving it a function name, and then calling it when needed.

Twey
04-06-2007, 10:39 PM
Worked around, not fixed. A fix is a solution that produces exactly the same (or better) costs and benefits as the original. A workaround is a compromise, something that doesn't work quite as well as the original. In this case, the added cost is that of efficiency: it's terribly inefficient to call that function every time you add a new element to the DOM, especially if you're adding lots of elements.

mburt
04-07-2007, 01:33 AM
What do you want help with?

mburt
04-07-2007, 10:37 AM
Man i'm very sorry but theres a problem... -

<html>
<body>
<div id="dragable" onmousedown="stard(this)" style="position: absolute; height: 100px; width: 100px; border: 1px solid; top: 5cm; left: 5cm;">PcBrainBuster</div>
<script>
function stard(item) {
document.onmousemove = function() {
item.style.left = event.clientX-(event.clientX-item.offsetLeft)
item.style.top = event.clientY-(event.clientY-item.offsetTop)}
document.onmouseup = function() {document.onmousemove=null}
}
</script>
</body>
</html>

Theres really only one problem that i've detected but and it seems that its the positioning area in the script... Very sorry for the whole hassly as usual but hey...
The positioning of well, everything on the page is screwed up. You don't even have a <head> tag, which is required.
The problem is that the "offset" for the x and y values must be called outside your onmousemove function:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Drag/Drop</title>
<script type="text/javascript">
function stard(item) {
var offsetx = (event.clientX-item.offsetLeft);
var offsety = (event.clientY-item.offsetTop);
document.onmousemove = function() {
item.style.left = event.clientX-offsetx;
item.style.top = event.clientY-offsety;
}
document.onmouseup = function() {document.onmousemove=null}
}
</script>
</head>
<body>
<div id="dragable" onmousedown="stard(this)" style="position: absolute; height: 100px; width: 100px; border: 1px solid; top: 5cm; left: 5cm;">PcBrainBuster</div>
</body>
</html>
That gives you the offset before you move your mouse.

shachi
04-07-2007, 11:03 AM
pcbrainbuster: It'd be very helpful for us to help you if you could describe your problem a little bit more briefly than just saying: "Please help me!", without actually having a problem. If you want to learn how a drag and drop system works then I suggest you ask so, if not and you simply want to build one yourself then I wouldn't call that a wise decision(which I learnt from the experts here), why re-invent the wheel when there are dozens of libraries which support drag and drop already? If not then you'll just be wasting your time.



Well if you will go back a few DOZEN PAGES then YOU'll KNOW !!!


As far as I remember you never said you had a problem!




// from your first post.

Again as always I have yet more questions... And this time as the title suggests is "how do I create a script that will allow drag on an object"...


As this statement clearly says, you just wanted to know "how" to create a dnd script and to my concern, my fellow colleague mburt has already shown you a basic script and me too have already described you the principles of dnd.

Phew!! That was long.

mburt
04-07-2007, 02:24 PM
When you asked for "how" to do something, or an example of one, we gave you one. All of the sudden, you destroy the script for some reason and expect us to fix it.
-Your invalid use of markup
-Misrepresenting the code I gave you
-Ranting on the forums

These three inqualities do not help us at all.
If you need to ask a question, ask it. But don't come running to us when you encounter every single problem.

pcbrainbuster
04-07-2007, 03:34 PM
Lol, I did not mean the first post :), but what was I to do with the head tag in this case (I had no use for it), sooooo many sites just say that the head is only needed when you want to load something quicker then the body as head is first loaded then the body...

riptide
04-10-2007, 03:16 PM
um... thanks mburt and Twey.
that was connected to the getElementsByClassName function right?