Outstandingly excellent javascript drag-and-drop tutorial withworking code

T

Thomas 'PointedEars' Lahn

pete said:
It's concise, it's comprehensible, it's complete, and it's correct; a
thing of beauty:

http://luke.breuer.com/tutorial/javascript-drag-and-drop-tutorial.aspx

It is nowhere close. A *requirement* for global variables, "IE is retarded"
instead of an explanation of different DOMs, proprietary event-handler
attributes, `$' functions, unncessary `innerHTML', no feature tests
whatsoever, disregard for left-handed mice, Prototype.js recommendation.
Save your money.

And you want to stop recommending it.


PointedEars
 
P

pete

It is nowhere close.  A *requirement* for global variables, "IE is retarded"
instead of an explanation of different DOMs, proprietary event-handler
attributes, `$' functions, unncessary `innerHTML', no feature tests
whatsoever, disregard for left-handed mice, Prototype.js recommendation.  
Save your money.

PointedEars

lmao! I gotta' admit it, PE; you are unique, a very Platonic ideal
unto yourself. Thanks for pointing out these shortcomings. They are
points that further my JS education.

For example, I've been too dense to grok that code that handles
multiple interdependent events need have no globals; I'll be on the
lookout for some of that globals-free code. And I've seen hundreds of
posts in this group that list in detail the retardations of IE, so I
don't agree that every further post that criticizes IE has to rehash
those IE issues. And I still don't see where the writer recommends
Prototype.js; I thought instead that he picked up some useful
Prototype.js code, and good on him for that.

But hold. This is of course all just me and my petty cavils. Canards,
too.

I do appreciate your taking the time to respond in detail: thank you
so much again.
And you want to stop recommending it.

Well, I dunno. I believe that IF:

1. one is a Javascript developer; and
2. one wants/needs to include some easy drag-and-drop JS code in one's
app; and
3. one doesn't have the know-how to implement such code from scratch;
and
4. one has been discouraged by the opacity of earlier d-n-d tutorials;
and
5. one can put up with the putative shortcomings that Pointed Ears
rags on above

THEN:

One could do no better, impo, than to consider the tut at

http://luke.breuer.com/tutorial/javascript-drag-and-drop-tutorial.aspx

Best to all,

-- pete
 
G

Garrett Smith

[...]

One could do no better, impo, than to consider the tut at

Better is relative and even the best can do better.

You could, for example, think about it critically, asking what's wrong
with this? and then in the recommendation, you could also list those
things. You can also list things that were unclear or questionable, such
as: "I saw a comment about a bug in Safari but I couldn't reproduce that."

Garrett
 
R

RobG

lmao! I gotta' admit it, PE; you are unique, a very Platonic ideal
unto yourself. Thanks for pointing out these shortcomings. They are
points that further my JS education.
Good.


For example, I've been too dense to grok that code that handles
multiple interdependent events need have no globals; I'll be on the
lookout for some of that globals-free code.

Follow the link in the article to the QuirksMode example - look ma, no
globals. If you want to know more about how to avoid global variables,
read up on the module pattern and private and public members in
javascript.

Here's a couple to get you going:

<URL: http://michaux.ca/articles/module-pattern-provides-no-privacy-at-least-not-in-javascript-tm<URL: http://michaux.ca/articles/an-important-pair-of-parens >

About closures in detail:
<URL: http://jibbering.com/faq/notes/closures/ >

While you're reading about and playing with closures, come back here
and ask questions, I'm sure you'll have plenty.

And I've seen hundreds of
posts in this group that list in detail the retardations of IE, so I
don't agree that every further post that criticizes IE has to rehash
those IE issues.

You are referencing an article, not a post here. It is unreasonable to
expect that everyone who reads that article is even aware of this
group, much less of posts here about various browser differences and
how they might apply to a drag and drop library. Statements like:

| // IE is retarded and doesn't pass the event object

are unnecessarily unprofessional, simply remove the second to fourth
words inclusive and you have a much more professional comment (and
don't appear to be ignorant of how the various event models evolved at
the same time). The language of other code comments is quite
reasonable.

And I still don't see where the writer recommends
Prototype.js; I thought instead that he picked up some useful
Prototype.js code, and good on him for that.

"Useful" depends on your point of view - Position.js uses user agent
based browser sniffing and has an "isOpera" function, so at least some
of it can be improved upon.

The code in the article has a $() function that simply calls
document.getElementById() and is used precisely once. So to save
typing 22 characters, the author wrote a function of 53 characters
and spaces (plus a bunch more for the comment). Consider using
instead:

var $ = document.getElementById;

within the scope it is required. No global "$", no extra function
call, far fewer characters to transmit and exactly (more or less) the
same functionality.


[...]
I do appreciate your taking the time to respond in detail: thank you
so much again.


Well, I dunno. I believe that IF:

1. one is a Javascript developer; and
2. one wants/needs to include some easy drag-and-drop JS code in one's
app; and

The code has basic drag functionality, but no "drop" functionality as
would be expected by a javascript developer looking for a drag-n-
*drop* tutorial. Where is the notification to other elements that a
dragged element has just been dropped on them? Or passed over/under/
through them?

3. one doesn't have the know-how to implement such code from scratch;
and

From the article, they are still ignorant about the dropping bit.
4. one has been discouraged by the opacity of earlier d-n-d tutorials;
and
5. one can put up with the putative shortcomings that Pointed Ears
rags on above

And the lack of half the claimed functionality.

If you want comments on an article, it is best to simply ask for a
review.

There must have been thousands of similar articles written over the
years, there is probably far more benefit to the author in writing
them than to the reader in reading them. Likely the author learned a
lot in writing the article, but his education is not complete (and
likely never will be in regard to javascript).
 
T

Thomas 'PointedEars' Lahn

RobG said:
The code in the article has a $() function that simply calls
document.getElementById() and is used precisely once. So to save
typing 22 characters, the author wrote a function of 53 characters
and spaces (plus a bunch more for the comment). Consider using
instead:

var $ = document.getElementById;

within the scope it is required. No global "$", no extra function
call, far fewer characters to transmit and exactly (more or less) the
same functionality.

It does not work as you suggest because the calling object would not be that
referred to by `document' anymore, but the Global Object. As a result, at
least MSHTML would throw an exception. I had to observe that when writing
JSX:dhtml.js years ago and I presume it still holds true. So a wrapper is
required if you want an alias for this, but it should have a better, self-
descriptive identifier (like `dom.getEBI' etc. in JSX:dhtml.js). Since then
this method included also feature testing for the MSHTML 4 and NS 4 DOMs,
but it would appear that these can either be safely discarded in the near
future or moved to compatibility libraries.


PointedEars
 
G

Garrett Smith

It does not work as you suggest because the calling object would not be that
referred to by `document' anymore, but the Global Object. As a result, at
least MSHTML would throw an exception. I had to observe that when writing
JSX:dhtml.js years ago and I presume it still holds true. So a wrapper is
required if you want an alias for this, but it should have a better, self-
descriptive identifier (like `dom.getEBI' etc. in JSX:dhtml.js). Since then
this method included also feature testing for the MSHTML 4 and NS 4 DOMs,
but it would appear that these can either be safely discarded in the near
future or moved to compatibility libraries.
I see your case, but I have a few disagreements.

Calling a host method with a different base object won't work in most
browsers. A function call gets its `this` value from that base object.
And for browsers that implement `getElementById` as a function and that
function needs to resolve a thisArg to the document to be searched, then
yes, the global object will be used and an error, either NativeError or
possibly TypeError would probably result.

However it *will* work in most IE versions. This is old news, appearing
in an old post of erik's weblog: "appendChild is not a function" and
restated as recently as two weeks ago wherein it was mentioned that MSIE
host methods tend to retain a reference to the base object.

var meth = document.getElementById;
meth("banner"); // Works in IE.

(Mentioned in "Need help with setTimeout"
<
MSIE host methods are not really functions although they do appear to
implement [[Call]]. This can be tested indirectly using
Function.prototype.call.call, as in:

var meth = document.getElementById;
Function.prototype.call.call(meth, document, "banner")

Exploring host methods further, I see IE9b has host methods appear to be
more like functions in that they have callable properties "call" and
"apply" that are not functions.

javascript: alert(typeof document.getElementById.call)

Though not all:
javascript: alert(typeof alert.call)

And still errors:
javascript: alert(typeof alert.blah = 1);

As far as creating a shortcut for document.getElementById, I can't see
it being justified.

Typing document.getElementById is not too long. Adding an extra function
to do that means your app has one more function in memory and for what
purpose? It's essentially a useless function that saves typing but comes
at a cost of keeping one more function in memory (with a scope chain,
etc) and the overhead of calling that additional function, which isn't
so significant, nowadays, but still redundant.

The only case where I can see using a wrapper is if you need to address
bugs in versions of IE where an element whose NAME attribute matches the
value of the parameter passed to document.getElementById. However, as
was pointed out years ago (I believe Gregor Koefler, said it): How about
just don't do that?

If typing is a problem, then an IDE autocomplete can be helpful.
Intelli-J and Eclipse are both nice.

Garrett
 
T

Thomas 'PointedEars' Lahn

Garrett said:
I see your case, but I have a few disagreements.

Well, you are rather prone to misconceptions.
Calling a host method with a different base object won't work in most
browsers.

I believe I have said that.
[preaching to the choir]
However it *will* work in most IE versions.

It sure did not work properly back then. Perhaps it was not MSHTML or it
was another method who was the culprit. Anyhow, it was bad advice to be
corrected.
This is old news, appearing in an old post of erik's weblog: "appendChild
is not a function" and

You don't mean the guy that completely botched JScript/MSHTML, do you?
restated as recently as two weeks ago wherein it was mentioned that MSIE
host methods tend to retain a reference to the base object.

It is an unnecessary risk to take, especially considering a proprietary,
closed source implementation; a sure sign of a script-kiddie. Why am I not
surprised to see you recommending that?
var meth = document.getElementById;
meth("banner"); // Works in IE.

It might work *for this method* in Wine IE 5.0 to 7.0 (I had no problems
now, but the test were only superficial and with `javascript:' in the
Address Bar). Doing that is not standard practice as far as Microsoft is
concerned, so it may very well change in one of the next versions. It is
just asking for trouble.
just don't do that?

Exactly.


PointedEars
 
G

Garrett Smith

Is that a typo?

Yes -- that was a typo. I meant:

javascript: alert(alert.blah = 1);

That throws an error in IE9.

Maybe I'm missing something here, but why shouldn't this
produce an error? The result of |typeof alert.blah| is not a valid lvalue.

It should produce an error, and for the reason you are getting at,
however it seems that "not a valid lvalue" seems a bit off as well. I
can't provide a detailed answer at this time.

Garrett
 
T

Thomas 'PointedEars' Lahn

Thomas said:
Garrett said:
Calling a host method with a different base object won't work in most
browsers.

I believe I have said that.
Essentially.
[preaching to the choir]
However it *will* work in most IE versions.

It sure did not work properly back then. Perhaps it was not MSHTML or it
was another method who was the culprit.

There, I knew it (I cannot remember ever having written code without good
reason):

--- dhtml-commented.js ---

if (jsx_object.isMethod(document, "getElementById"))
{
/**
* @param s : string
* @return Element|null
*/
return function(s) {
/* wrapper method required to avoid "invalid op. on prototype"
exception */
return document.getElementById(s);
};
}

---

That exception is thrown in *Mozilla*-based browsers, by the Gecko DOM, when
doing as Stefan suggested. Turns out that it applies one way or the other
(type of exception differs) to *all* known DOMs *except* that of MSHTML
(with regard to the versions of it that I have tested so far), which is, at
least in my book, far worse.
Anyhow, it was bad advice to be corrected.

AISB.


PointedEars
 
G

Garrett Smith

Well, you are rather prone to misconceptions.

Aside from the typo that Stephen Weiss caught (thanks), did I post
something wrong? Seems not.

You referred to "base object" as "calling object" and called that global
object. That's wrong terminology. If the aforementioned code been
defined in global context, then yes, the base object would be the global
object, but I disagree with calling that a "calling object" because it
is not the correct terminology.

In all IE versions so far, `document.getElementById` is a callable host
object that is not actually a function. There isn't any spec that states
that the thisArg matters for these methods. Does it matter? Maybe? Is it
safe to assume it doesn't? Of course not! -- And I never have suggested
otherwise.

http://ecma262-5.com/ELS5_HTML_with_CorrectionNotes.htm#Section_11.2.3
Calling a host method with a different base object won't work in most
browsers.

I believe I have said that.
[preaching to the choir]

I did not write that.
It sure did not work properly back then. Perhaps it was not MSHTML or it
was another method who was the culprit. Anyhow, it was bad advice to be
corrected.

http://erik.eae.net/archives/2006/04/27/17.50.15/

Whether or not Erik was wrong about other points doesn't really matter.
That entry is the one that counts here.
You don't mean the guy that completely botched JScript/MSHTML, do you?

Dunno about that, but the entry itself points out the fact I stated.
it's quoted so search google for that string and you'll see.

Here...
It is an unnecessary risk to take, especially considering a proprietary,
closed source implementation; a sure sign of a script-kiddie. Why am I not
surprised to see you recommending that?

What a load of bs. First off, I never ever recommended doing that; I
recommended against doing that both here and in that other thread.

In "Need help with setTimeout", Gregor recommended:

| window.setTimeout(mf.reset, 10000);
|
| is what you want.

And I replied to explain why that can't be expected to work reliably.

| Passing the value of `mf.reset` to setTimeout will cause the function
| to execute in 10000 ms with a null base object. That cannot be
| expected to work reliably.
|
| It will submit the form in most versions of IE, but will result in an
| error in other implementations. MSIE is a notable exception, as its
| host objects tend to retain a reference to their base object.

So what I did was I pointed out that what you stated "doesn't work in
IE" was not true. I never recommended such things.

I'd appreciate if you'd not make such false statements about me.

The mistake I made in the other thread was not helping the OP enough. I
deliberately decided not give away too much, so as to make him think
about it. I think I misjudged and did not reveal enough.

Garrett
 
G

Garrett Smith

Essentially.

It appears that you are conversing with yourself.
[preaching to the choir]
However it *will* work in most IE versions.

It sure did not work properly back then. Perhaps it was not MSHTML or it
was another method who was the culprit.

There, I knew it (I cannot remember ever having written code without good
reason):

Knew what? That the base object matters in most browsers?
--- dhtml-commented.js ---

if (jsx_object.isMethod(document, "getElementById"))
{
/**
* @param s : string
* @return Element|null
*/
return function(s) {
/* wrapper method required to avoid "invalid op. on prototype"
exception */
return document.getElementById(s);
};
}

What do you return if document.getElementById is not available?

Forget about "Mozilla" for a second. Think bigger. The exception is
thrown in any browser where the thisArg to the getElementById function
matters. That is likely to happen in any browser that uses DOM
prototypes. Gecko happens to be one such browser.
doing as Stefan suggested. Turns out that it applies one way or the other
(type of exception differs) to *all* known DOMs *except* that of MSHTML
(with regard to the versions of it that I have tested so far), which is, at
least in my book, far worse.

It's been done and now you're repeating what I wrote earlier.

Again, I did not recommend using that approach. I'm fairly keen on how
function calls work, how DOM prototypes work, and IE host objects, as
they pertain to web page scripting. I recommended *agaist* using that
approach whenever I see it because it doesn't work in IE.

Please don't suggest that I recommended doing that.

Garrett
 
T

Thomas 'PointedEars' Lahn

Garrett said:
It appears that you are conversing with yourself.

It appears that you are not paying attention.
[preaching to the choir]
However it *will* work in most IE versions.
It sure did not work properly back then. Perhaps it was not MSHTML or
it was another method who was the culprit.
There, I knew it (I cannot remember ever having written code without good
reason):

Knew what? That the base object matters in most browsers?

No, that I had a reason for not using a simple alias as suggested by
_Stefan_.
What do you return if document.getElementById is not available?

Depends on the remaining alternatives. Learn to read.
Forget about "Mozilla" for a second. Think bigger.

You are not paying attention. Here I have been referring to the main reason
why I wrote dhtml.js the way I have written it.
The exception is thrown in any browser where the thisArg to the
getElementById function matters. That is likely to happen in any browser
that uses DOM prototypes.

You don't say!
Gecko happens to be one such browser.

Gecko is not a browser.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Garrett said:
Correction: Because it doesn't work cross-browser.

ACK, my bad. I do not agree with some of your conclusions, though.
More later.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Garrett said:
Aside from the typo that Stephen Weiss caught (thanks), did I post
something wrong? Seems not.

You referred to "base object" as "calling object" and called that global
object. That's wrong terminology.

"base object" is wrong terminology, too. "`this' value" would be correct.
If the aforementioned code been defined in global context, then yes, the
base object would be the global object,
Questionable.

but I disagree with calling that a "calling object" because it is not the
correct terminology.

The concept was clear, though.
Calling a host method with a different base object won't work in most
browsers.

I believe I have said that.
[preaching to the choir]

I did not write that.

That's called a summary, stupid.
http://erik.eae.net/archives/2006/04/27/17.50.15/

Whether or not Erik was wrong about other points doesn't really matter.
That entry is the one that counts here.


Dunno about that,

Apparently you didn't mean him. Which keeps your argument fallacious,
though.
but the entry itself points out the fact I stated.
it's quoted so search google for that string and you'll see.

Here...

Let's eat sh*t -- a million flies can't be wrong.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Stefan said:
Thomas said:
No, that I had a reason for not using a simple alias as suggested by
_Stefan_.

JFTR, I didn't suggest this. [...]

You're absolutely right. Sorry, Garrett got me confused with his "Stephen
Weiss" in < RobG suggested
it, of course, in
<earlier in this thread, and it was (t)his posting that my correction was
directed at (albeit the correction itself was evidently flawed).


PointedEars
 
G

Garrett Smith

JFTR, I didn't suggest this.

Right, well Thomas' last few posts have seemed not very rational and
contained a number of mistakes.

RobG made that suggestion and right after advising to use
document.getElementById. He mentioned th drawbacks to creating a
wrapper, as I did and pointed out that it's unnecessary, as I did.

ISTM the subject of how to use getElementById been done to death. But
maybe not.
I did admit (in a different thread, a about two months ago) that I
sometimes use $ as a shortcut for document.getElementById, but not in
the form of a direct reference. I use something like |var $ =
someObj.gEBI|, which doesn't have the problem discussed in this thread,
as long as gEBI doesn't make use of its |this| value.

That works so long as `someObj.gEBI` does not make references to `this`,
expecting it to be `someObj`. But, what also works:

document.getElementById

Just remember not to give any element's NAME a value that equals another
element's ID, and vice-versa.

Garrett
 
G

Garrett Smith

Stands.

And after all that noise of yours, nothing's changed. The
"misconceptions" you called foul on? Nope, only misconcpetions were
yours with attributing the idea to the wrong person, posting wrong
information on browsers where it works and doesn't, mentioning browsers
rather than applying the concept of prototype-based functions, and
giving a correctable, but understandable (though still imprecise)
explanation of context/thisArg.

All that wasted time for you.
Calling a host method with a different base object won't work in most
browsers.

I believe I have said that.

[preaching to the choir]

I did not write that.

That's called a summary, stupid.

http://erik.eae.net/archives/2006/04/27/17.50.15/

Whether or not Erik was wrong about other points doesn't really matter.
That entry is the one that counts here.


Dunno about that,

Apparently you didn't mean him. Which keeps your argument fallacious,
though.

Nothing fallacious at all; just more bs from thomas.
Let's eat sh*t -- a million flies can't be wrong.

Crying foul again?

Was the article incorrect?

You offered no valid, rational criticism in your response. About the
best we can do is come to the realization that you are irrational and no
such conclusions about the article's correctness can be made from your
comments.

Garrett
 

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,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top