Why won't the following work in FireFox?

N

Nathan Sokalski

I have the following code which allows you to drag a div in IE, and have it
then move back to it's natural position when you release the mouse button:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><script type="text/javascript">var draggable=0;</script></head>
<body>
<div id="div1"
style="width:300px;height:300px;background-color:eek:range;"></div>
<div id="div2" style="width:300px;height:300px;background-color:green;"
onmousedown="draggable=1;this.style.position='absolute';this.style.left=event.x-25+'px';this.style.top=event.y-25+'px';"
onmousemove="if(draggable==1){this.style.left=event.x-25+'px';this.style.top=event.y-25+'px';}"
onmouseup="draggable=0;this.style.position='static';"></div>
</body>
</html>


I have written what I would expect to do the same thing in other browsers (I
replaced event.x/event.y with event.layerX/event.layerY). Here is that code:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><script type="text/javascript">var draggable=0;</script></head>
<body>
<div id="div1"
style="width:300px;height:300px;background-color:eek:range;"></div>
<div id="div2" style="width:300px;height:300px;background-color:green;"
onmousedown="draggable=1;this.style.position='absolute';this.style.left=event.layerX-25+'px';this.style.top=event.layerY-25+'px';"
onmousemove="if(draggable==1){this.style.left=event.layerX-25+'px';this.style.top=event.layerY-25+'px';}"
onmouseup="draggable=0;this.style.position='static';"></div>
</body>
</html>


However, when I attempt to drag the div in FireFox it just sort of "jumps
around", it definitely isn't doing what the IE version did in IE. did I do
something wrong? Was there something that should have been in both of the
versions that I forgot? Any help would be appreciated. Thanks.
 
D

dNagel

heres my version ...


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript">
var draggable=0;

function onMDown(e) {
e = e || window.event;
var el = e.target || e.srcElement;
draggable=1;
el.style.position='absolute';
el.style.left=( e.x || e.clientX )-25+'px';
el.style.top=( e.y || e.clientY )-25+'px';
}

function onMMove(e) {
e = e || window.event;
var el = e.target || e.srcElement;
if(draggable==1){
el.style.left=( e.x || e.clientX )-25+'px';
el.style.top=( e.y || e.clientY )-25+'px';
}
}

function onMUp(e) {
e = e || window.event;
var el = e.target || e.srcElement;
draggable=0;
el.style.position='static';
}
</script>
</head>
<body>
<div
id="div1"
style="width:300px;height:300px;background-color:eek:range;">
</div>
<div
id="div2"
style="width:300px;height:300px;background-color:green;"
onMouseDown="onMDown(event)"
onMouseMove="onMMove(event)"
onMouseUp="onMUp(event)">
</div>
</body>
</html>



D.
 
D

David Mark

I have the following code which allows you to drag a div in IE, and have it
then move back to it's natural position when you release the mouse button:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Why are you using XHTML transitional for a new document? And why use
XHTML at all if you are going to serve this as HTML?
<html>
<head><script type="text/javascript">var draggable=0;</script></head>
<body>
<div id="div1"
style="width:300px;height:300px;background-color:eek:range;"></div>
<div id="div2" style="width:300px;height:300px;background-color:green;"
onmousedown="draggable=1;this.style.position='absolute';this.style.left=eve­nt.x-25+'px';this.style.top=event.y-25+'px';"

Don't use the x/y properties. They are non-standard and unreliable.
And what is the significance of 25?
onmousemove="if(draggable==1){this.style.left=event.x-25+'px';this.style.to­p=event.y-25+'px';}"
onmouseup="draggable=0;this.style.position='static';"></div>
</body>
</html>

I have written what I would expect to do the same thing in other browsers (I
replaced event.x/event.y with event.layerX/event.layerY). Here is that code:

Using layerX/layerY is also a bad idea. Use pageX/Y if defined and
clientX/Y otherwise. For the latter pair you must add the scroll
position of the document. You will find that most browsers support
one pair or the other (or both.) If neither is defined, you should
skip the drag and drop operation as the results will be unpredictable.
 
D

David Mark

heres my version ...

I'm not sure what happened to my reply to this thread.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript">
var draggable=0;

function onMDown(e) {
e = e || window.event;

You don't need this line. Your inline handler passed the event
object.
var el = e.target || e.srcElement;

You wouldn't need this line if you passed "this" as a second
parameter.
draggable=1;
el.style.position='absolute';
el.style.left=( e.x || e.clientX )-25+'px';

As I mentioned in my missing post, you shouldn't use the x/y pair.
Use pageX/Y if defined, then try clientX/Y and then give up as x/y and
layerX/layerY are unpredictable. This works reliably on virtually
every modern browser (and many older ones too.)

There are a few problems with the above line of code. For one, your
test is off. If e.x is 0 and e.clientX is undefined, you will end up
with NaNpx. Same if e.x and e.clientX are both undefined. Then there
is the scroll position of the document to deal with (clientX/Y returns
coordinates relative to the viewport.)

I don't see the significance of 25 either, but that is from the
original.
el.style.top=( e.y || e.clientY )-25+'px';

Same problems here.

[snip]
<div
id="div2"
style="width:300px;height:300px;background-color:green;"
onMouseDown="onMDown(event)"
onMouseMove="onMMove(event)"
onMouseUp="onMUp(event)">

You don't want the mouseup or mousemove listeners attached to just the
dragged element. They need to be attached to the document.
 
N

Nathan Sokalski

I am using XHTML because the place where I will be using these techniques is
in an ASP.NET page, which is created using that header. The x/y properties
are only used in the IE version; both pageX/Y and clientX/Y gave an alert
saying they were undefined, so I did not know what else to use for IE. Is
there something else that works in IE? I would like to skip the drag & drop,
but my boss won't let me.
--
Nathan Sokalski
(e-mail address removed)
http://www.nathansokalski.com/

I have the following code which allows you to drag a div in IE, and have
it
then move back to it's natural position when you release the mouse button:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Why are you using XHTML transitional for a new document? And why use
XHTML at all if you are going to serve this as HTML?
<html>
<head><script type="text/javascript">var draggable=0;</script></head>
<body>
<div id="div1"
style="width:300px;height:300px;background-color:eek:range;"></div>
<div id="div2" style="width:300px;height:300px;background-color:green;"
onmousedown="draggable=1;this.style.position='absolute';this.style.left=eve­nt.x-25+'px';this.style.top=event.y-25+'px';"

Don't use the x/y properties. They are non-standard and unreliable.
And what is the significance of 25?
onmousemove="if(draggable==1){this.style.left=event.x-25+'px';this.style.to­p=event.y-25+'px';}"
onmouseup="draggable=0;this.style.position='static';"></div>
</body>
</html>

I have written what I would expect to do the same thing in other browsers
(I
replaced event.x/event.y with event.layerX/event.layerY). Here is that
code:

Using layerX/layerY is also a bad idea. Use pageX/Y if defined and
clientX/Y otherwise. For the latter pair you must add the scroll
position of the document. You will find that most browsers support
one pair or the other (or both.) If neither is defined, you should
skip the drag and drop operation as the results will be unpredictable.
 
R

Randy Webb

Nathan Sokalski said the following on 10/17/2007 12:12 PM:
I am using XHTML because the place where I will be using these techniques is
in an ASP.NET page, which is created using that header.

Nice to know Microsoft products generate a document that a Microsoft
browser can't handle.
 
D

David Mark

I am using XHTML because the place where I will be using these techniques is
in an ASP.NET page, which is created using that header. The x/y properties

That seems an odd choice for a Microsoft product.
are only used in the IE version; both pageX/Y and clientX/Y gave an alert
saying they were undefined, so I did not know what else to use for IE. Is

The clientX/Y properties are certainly present in IE.
there something else that works in IE? I would like to skip the drag & drop,
but my boss won't let me.

There is some very simple cross-browser drag and drop code in this
project:

http://code.google.com/p/niceshowcase/

You will see that it only uses pageX/Y and clientX/Y.
 
D

dNagel

You don't need this line. Your inline handler passed the event
object.
You do need it... event is not valid in firefox, so it will pass
undefined instead of what you think
should be the event object. FFox always passes the event object into
the into an event procedure.
If you do not use my code exactly as I have written it, it will fail. I
promise you that.
You wouldn't need this line if you passed "this" as a second
parameter.
Why pass it as a parameter when the event object already has it as a
property.
As I mentioned in my missing post, you shouldn't use the x/y pair.
Use pageX/Y if defined, then try clientX/Y and then give up as x/y and
layerX/layerY are unpredictable. This works reliably on virtually
every modern browser (and many older ones too.)
sounds good to me.
There are a few problems with the above line of code. For one, your
test is off. If e.x is 0 and e.clientX is undefined, you will end up
with NaNpx. Same if e.x and e.clientX are both undefined. Then there
is the scroll position of the document to deal with (clientX/Y returns
coordinates relative to the viewport.)

I don't see the significance of 25 either, but that is from the
original.
agreed, but what it does is "position the cursor" a bit inside of the
object so that accelerated mouse
movement does not allow the mouse to escape the "capture".
el.style.top=( e.y || e.clientY )-25+'px';

Same problems here.

agreed.
[snip]


<div
id="div2"
style="width:300px;height:300px;background-color:green;"
onMouseDown="onMDown(event)"
onMouseMove="onMMove(event)"
onMouseUp="onMUp(event)">

You don't want the mouseup or mousemove listeners attached to just the
dragged element. They need to be attached to the document.
sounds good to me too...

I have not tried it so I'll take your word for it.



D.
 
D

David Mark

You do need it... event is not valid in firefox, so it will pass
Wrong.

undefined instead of what you think

If that were true, your code would try to use window.event, which
certainly isn't valid in FF.
should be the event object. FFox always passes the event object into
the into an event procedure.

You need to re-read your code.
If you do not use my code exactly as I have written it, it will fail. I
promise you that.

You can promise anything you want. You are still incorrect.
Why pass it as a parameter when the event object already has it as a
property.

It is simpler to do it that way. The resulting code is smaller as
well.
sounds good to me.



agreed, but what it does is "position the cursor" a bit inside of the
object so that accelerated mouse
movement does not allow the mouse to escape the "capture".

That is a pretty unreliable approach and will make the element jump
every time you drag it. Just attach the onmousemove and onmouseup
handlers to the document.
 
D

dNagel

David said:

Well, if I;m so wrong, can you please explain to me (in a full example)
how you would implement your suggestions?

This is as close as I could get to implementing your suggestions.
Removing the -25px makes the drag impossible
with a highly accelerated mouse. Theres no way to pass ( this ) into a
document event procedure.

I should point out that I was wrong about needing the e= code in my
previous routines, but I don't see a way to
avoid it in the document routines this time around.

D.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript">
var draggable=0;

function onMDown(e,xThis) {
draggable=1;
xThis.style.position='absolute';
xThis.style.left=( e.pageX || e.clientX )-25+'px';
xThis.style.top=( e.pageY || e.clientY )-25+'px';
}

document.onmousemove = function(e) {
e = e || window.event;
var el = e.target || e.srcElement;
if(el && draggable==1){
el.style.left=( e.pageX || e.clientX )-25+'px';
el.style.top=( e.pageY || e.clientY )-25+'px';
}
}

document.onmouseup=function(e) {
e = e || window.event;
var el = e.target || e.srcElement;
draggable=0;
el.style.position='static';
}
</script>
</head>
<body>
<div
id="div1"
style="width:300px;height:300px;background-color:eek:range;">
</div>
<div
id="div2"
style="width:300px;height:300px;background-color:green;"
onMouseDown="onMDown(event,this)"
</div>
</body>
</html>
 
D

David Mark

Well, if I;m so wrong, can you please explain to me (in a full example)

As you noted below, there is no if about it.
how you would implement your suggestions?

My drag and drop code looks very different from this. There's no
quick fix.
This is as close as I could get to implementing your suggestions.
Removing the -25px makes the drag impossible

I don't see why that would make any difference. Regardless, you
should store the mouse coordinates and position of the element on
mousedown and then calculate and apply the difference on each
mousemove event.
with a highly accelerated mouse. Theres no way to pass ( this ) into a
document event procedure.

That's not quite true.

document.onclick = function(e) { alert(this); };

Of course, "this" is the document object in this case.

Here is a hint. You have a reference to the element in question in
the onmousedown handler. And you don't need to assign the document
handlers until this point. So you can use a closure to keep the
element reference in scope. Alternatively, just store the reference
to the element in a global variable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top