Cross Browser or Quit?

M

Martin Rinehart

On my latest drag code,

http://www.martinrinehart.com/examples/js-drag-code.html

the blue slider is constrained. This is the entire display function
(excluding the end-of-drag logic):

y = Math.max( Math.min(400,y), 100 );
blue.me.style.top = y + 'px';

The slider is not bound in Opera 9, PC. The slider is constrained to y
between 100 and 400 in six other browsers I just tested. Is it time to
quit?
 
D

David Mark

Martin said:
On my latest drag code,

http://www.martinrinehart.com/examples/js-drag-code.html

the blue slider is constrained. This is the entire display function
(excluding the end-of-drag logic):

y = Math.max( Math.min(400,y), 100 );
blue.me.style.top = y + 'px';

The slider is not bound in Opera 9, PC. The slider is constrained to y
between 100 and 400 in six other browsers I just tested. Is it time to
quit?

Well, lets see.

<body
onselectstart='return false'
onmousedown='return false'
onload=init()>

That makes for a pretty bad example. It is invalid and I had to
disabled scripting to select text on the page. Attach and detach the
mousedown listener on drag and drop respectively. I don't know why
you feel you need the selectstart event as I've never used it for
anything.

dragger = {

MAX: 1000000,


Why is this all caps?


callback: undefined, // function to send x, y


You can lose this.


// wrinkle: The mouse is not likely to be on the
// top/left corner of the draggable.

// object = mouse + delta
deltaX: undefined, deltaY: undefined,
mouseX: undefined, mouseY: undefined,
objectX: undefined, objectY: undefined,

ceiling: undefined, // event trapper


And these.


init: function () {
this.ceiling =
document.createElement( 'div' );

var z = this.ceiling.style;
z.position = 'absolute'; z.top = 0; z.left = 0;


Strings not numbers.


z.zIndex = this.MAX;
this.ceiling.onmousemove = dragger.moved;
this.ceiling.onmouseup = dragger.stopDrag;


I would lose the "ceiling" too.


}, // end of init()

moved: function ( evt ) {
if ( !evt ) { evt = window.event; }
// 'this' is the drag object

dragger.objectX = evt.clientX + dragger.deltaX;
dragger.objectY = evt.clientY + dragger.deltaY;


That won't work reliably cross-browser. Did you look at examples of
mouse position reporting? And it is best to re-position the element
based on the difference between the original and current mouse
position. Then you can lose deltaX/Y.


dragger.callback(
dragger.objectX, dragger.objectY );
},

startDrag: function ( callback, evt, location_ ) {

this.callback = callback;
this.mouseX = evt.clientX;
this.mouseY = evt.clientY;


You can't rely on clientX/Y alone.


this.objectX = location_.left_;
this.objectY = location_.top_;


What is with the underscores?


this.deltaX = this.objectX - this.mouseX;
this.deltaY = this.objectY - this.mouseY;


You don't need this.


if ( !this.ceiling ) { this.init(); }

this.ceiling.style.height =
document.body.clientHeight;
this.ceiling.style.width =
document.body.clientWidth;


This will only work in quirks mode in IE >= 6. And what of the
documentElement?

[snip]

Is it time to quit? Depends on what you want to get out of this.
Certainly it isn't ready for prime time. I tried it on FF3 and it was
unusable. Every time the boxes hit an impediment, I would end up
dragging with the mouse button up. Trying to cancel the drag in this
case seemed to be a problem as well.
 
M

Martin Rinehart

        y = Math.max( Math.min(400,y), 100 );
        blue.me.style.top = y + 'px';

This works:

if ( y < 100 ) { y = 100; }
if ( y > 400 ) { y = 400; }
 
E

Evertjan.

Martin Rinehart wrote on 14 dec 2008 in comp.lang.javascript:
This works:

if ( y < 100 ) { y = 100; }
if ( y > 400 ) { y = 400; }

if ( y < 100 )
y = 100
else if ( y > 400 )
y = 400;

a tiny bit faster?
 
M

Martin Rinehart

<body
onselectstart='return false'
onmousedown='return false'
onload=init()>

That makes for a pretty bad example. It is invalid and I had to
disabled scripting to select text on the page. Attach and detach the
mousedown listener on drag and drop respectively.

Good idea. Will do.
I don't know why
you feel you need the selectstart event as I've never used it for
anything.

onmousedown alone works, but not in all the browsers I've tested. Some
need both.
MAX: 1000000,

Why is this all caps?

Because I disagree with Crockford on this point. (And I suspect you
knew that.)
callback: undefined, // function to send x, y

I agree with Crockford re declaring vars first, and extend that to
object attributes.
init: function () {
this.ceiling =
document.createElement( 'div' );

var z = this.ceiling.style;
z.position = 'absolute'; z.top = 0; z.left = 0;
Strings not numbers.

My right index finger is in a splint. I'm not interested in the w3c's
validator's opinion. Is there a browser you can point me to that
actually requires strings?
z.zIndex = this.MAX;
this.ceiling.onmousemove = dragger.moved;
this.ceiling.onmouseup = dragger.stopDrag;

I would lose the "ceiling" too.

We discussed this. Without ceiling I have to trap events in the
document or body. You may be trapping events there for your own
purpose.
And it is best to re-position the element
based on the difference between the original and current mouse
position. Then you can lose deltaX/Y.

Good idea.
You can't rely on clientX/Y alone.

You're disagreeing with Quirksmode, here. What else do I need?
this.objectX = location_.left_;
this.objectY = location_.top_;

What is with the underscores?

Convention being to append to avoid mistaking my 'left_' from JS
'left'.
this.ceiling.style.height =
document.body.clientHeight;
this.ceiling.style.width =
document.body.clientWidth;

This will only work in quirks mode in IE >= 6. And what of the
documentElement?

Don't know what you are asking re documentElement. Your suggested
improvement is?
I tried it on FF3 and it was
unusable. Every time the boxes hit an impediment, I would end up
dragging with the mouse button up.

Hit an impediment?

Thanks for your time. One of my goals is to learn JavaScript, which I
used to think meant learning Crockford's good parts. Now I see that it
also means learning multiple dialects and speaking them all at once.
 
M

Martin Rinehart

if ( y < 100 )
   y = 100
else if ( y > 400 )
   y = 400;

a tiny bit faster?

Are you saying that the curly braces slow things down? That would mean
Crockford's convention, always use blocks, maybe needs some
rethinking?
 
E

Evertjan.

Martin Rinehart wrote on 14 dec 2008 in comp.lang.javascript:
Are you saying that the curly braces slow things down?

No, it is the added "else" sometimes forgoing the second compare.
That would mean
Crockford's convention, always use blocks, maybe needs some
rethinking?

I wouldn't know. I never use them for a single statement.
 
D

David Mark

Good idea. Will do.


onmousedown alone works, but not in all the browsers I've tested. Some
need both.

Which requires selectstart? I'll have to look at my drag and drop
module to see what I used, but I am sure it wasn't that.
Because I disagree with Crockford on this point. (And I suspect you
knew that.)

Your suspicions are unfounded. I have no idea what you agree or
disagree with.
I agree with Crockford re declaring vars first, and extend that to
object attributes.

Object properties. And you don't declare properties.
My right index finger is in a splint. I'm not interested in the w3c's
validator's opinion. Is there a browser you can point me to that
actually requires strings?

What validator? No need to point. You should never assume that a
host object will type convert property assignments.
We discussed this. Without ceiling I have to trap events in the
document or body. You may be trapping events there for your own
purpose.

Leave that to the calling script.
Good idea.


You're disagreeing with Quirksmode, here. What else do I need?
Huh?



Convention being to append to avoid mistaking my 'left_' from JS
'left'.

Why not use a different name?
Don't know what you are asking re documentElement. Your suggested
improvement is?

If you want to cover the document, you must include the
documentElement, unless you are assuming IE quirks mode (which would
be a bizarre assumption indeed.)
Hit an impediment?

The boxes were apparently constrained in some way. I really couldn't
make heads or tails of it.
Thanks for your time. One of my goals is to learn JavaScript, which I
used to think meant learning Crockford's good parts. Now I see that it
also means learning multiple dialects and speaking them all at once.

Crockford is a noted expert on the language, but he doesn't talk much
about cross-browser scripting. There are no "dialects" of Javascript,
but there are lots of different host environments (most are browsers),
each with their own features and quirks.
 
G

Gregor Kofler

Martin Rinehart meinte:
My right index finger is in a splint. I'm not interested in the w3c's
validator's opinion. Is there a browser you can point me to that
actually requires strings?

0 what? "0px"? "0em"? "0%"? Top and left always require a unit, and
therefore strings. In any browser I know of.

"...if you want to set the element's inline STYLE settings for left and
top, make sure to construct a string that includes the unit (such as
"140px") by appending the unit string to the integer value." [1]

Thanks for your time. One of my goals is to learn JavaScript, which I
used to think meant learning Crockford's good parts. Now I see that it
also means learning multiple dialects and speaking them all at once.

Drag and Drop is DOM stuff, hardly JS. And Crockford is about JavaScript.

Gregor

[1]
https://developer.mozilla.org/en/Using_Web_Standards_in_your_Web_Pages/Using_the_W3C_DOM
 
E

Evertjan.

Gregor Kofler wrote on 14 dec 2008 in comp.lang.javascript:
0 what? "0px"? "0em"? "0%"? Top and left always require a unit, and
therefore strings. In any browser I know of.

No, the zero does not require a specified unit, methinks.
 
G

Gregor Kofler

Evertjan. meinte:
Gregor Kofler wrote on 14 dec 2008 in comp.lang.javascript:


No, the zero does not require a specified unit, methinks.

Yes, my bad. Zeros don't need units.

Gregor
 
D

dhtml

Gregor said:
Evertjan. meinte:

Yes, my bad. Zeros don't need units.

Keep in mind that 0 is a number; "0" is a string.

I don't know of any cases where assigning a number to a CSS style
property would cause an error.

Using non-string values for assignment to a host object property that
expects a string value doesn't always work.

Using the expected type for a method or assignment to a host object will
have an outcome that is as clear as the specification defines it to be.
If you use a number, and it doesn't work, then it would be your fault.

The benefit to using a number instead of a string value would be that
requires 2 characters less (fewer bytes and less typing). A lot of web
pages use el.style.left = 0, and browsers that support CSS Style
declaration consistently support converting 0 to "0".

For examples,

document.title = null;
document.title = undefined;

have unspecified results that vary, whereas:

document.title = "null";

- can be expected to have a consistent outcome across all browsers that
support HTML DOM document.title.

In IE, using an object in an assignemnt will result in error, where
other browsers may call the object's toString method.

document.body.style.color = {
toString: function() {
return "rgb(10, 30, 90)";
}
}

So, as a general rule of thumb, it is a good idea to supply a string
value when a host object expects that.

Garrett
 
E

Evertjan.

dhtml wrote on 15 dec 2008 in comp.lang.javascript:
Keep in mind that 0 is a number; "0" is a string.

I don't know of any cases where assigning a number to a CSS style
property would cause an error.

Using non-string values for assignment to a host object property that
expects a string value doesn't always work.

Using the expected type for a method or assignment to a host object
will have an outcome that is as clear as the specification defines it
to be. If you use a number, and it doesn't work, then it would be your
fault.

The benefit to using a number instead of a string value would be that
requires 2 characters less (fewer bytes and less typing). A lot of web
pages use el.style.left = 0, and browsers that support CSS Style
declaration consistently support converting 0 to "0".

For examples,

document.title = null;
document.title = undefined;

have unspecified results that vary, whereas:

document.title = "null";

- can be expected to have a consistent outcome across all browsers
that support HTML DOM document.title.

In IE, using an object in an assignemnt will result in error, where
other browsers may call the object's toString method.

document.body.style.color = {
toString: function() {
return "rgb(10, 30, 90)";
}
}

So, as a general rule of thumb, it is a good idea to supply a string
value when a host object expects that.

I do not agree.

The 'general rule of thumb' is 'know what you are doing':

Any dom-value that expects a string will 'do' an automatic conversion if
a number is encountered in javascript.

So both
x.style.top = 0;
and
x.style.top = 0000;

wil allocate the string "0"
 
M

Martin Rinehart

Can anybody duplicate David Mark's FF3 issue? The white and red boxes
should be happily dragging anywhere you like.
 
D

David Mark

Can anybody duplicate David Mark's FF3 issue? The white and red boxes
should be happily dragging anywhere you like.

Doesn't really matter if anyone else can reproduce it. Take the
advice I have given you, including removing the "ceiling" (if only to
reduce the variables involved) and I will look at it again. It is
definitely fouled up as is.
 
D

David Mark

dhtml wrote on 15 dec 2008 in comp.lang.javascript:

















I do not agree.

The 'general rule of thumb' is 'know what you are doing':

Any dom-value that expects a string will 'do' an automatic conversion if
a number is encountered in javascript.

I don't see the connection between this assertion and knowing what you
are doing.
So both
x.style.top = 0;
and
x.style.top = 0000;

wil allocate the string "0"

No way you can guarantee that. You can't trust host objects at all.
Might as well add the two additional characters.

[snip]
 
M

Martin Rinehart

It is definitely fouled up as is.

I'm doing extremely picky tests (put mouse pointer on the dot in "!"
and drag) and some very unreasonable things (drag out of the browser,
left side, circle around the browser to the right side and reenter).
Locking in quite well.

You did notice that the blue box is constrained, as if it's a vertical
slider? The red and white boxes can be dragged all over. You can
arrow left or right from the blue box and still drag. This is the
scrollbar behavior on every browser I've tried. (Some limit the x-
distance. Some have no limit.)

I've introduced an MSIE bug, and there's a scrolling issue but
otherwise it's working well. I certainly appreciate your advice and
I've taken most of it. (The latest version is delta-free.)

When I can type again I'll even start quoting numbers. But you've
still not explained why this isn't a problem: without the ceiling,
what happens when some one drags a draggable over other things that
may be listening for mouseup and mousemove?
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top