Simpler loading through jQuery

D

David Mark

http://groups.google.com/group/jquery-dev/browse_thread/thread/3abf45d3fd4d50fc#

This never-ending thread has it all. "Edge cases", John Resig, IE
properties that "blow up" on access and enough wasted time to write a
whole new library.

And for what? So documents bloated by huge scripts can load
"faster." Lose the huge scripts and use the body's onload attribute.
End of story for all but the criminally incompetent.

More of the same:

http://groups.google.com/group/jquery-en/browse_thread/thread/70e8a050f60f8b08?hl=en#

jQuery is quite the "convenience." Write less; flail around in their
forums forever.
 
P

Peter Michaux


I had hoped my article would have had some influence and people would
no longer be interested in when the document is "ready" sometime
before window.onload. It is not ready when it is claimed to be
"ready".

http://peter.michaux.ca/articles/the-window-onload-problem-still

Even if it was ready when it is "ready", it would still leave elements
exposed for a short time without being enlivened. I think that the
approach of using document.ready will never be a true solution even
if an implementation is bug free.

on* HTML attributes or delegate listeners are both true solutions.

I think what is happening is that some people try to believe certain
things work, or can work, or will work just because that is the way
they want things to work.

David, my question to you is why are you reading the jQuery list?

Peter
 
D

David Mark


As a side note, it appears that the property (frameElement) that is
sending these guys around in circles responds favorably to the typeof
operator. One "working" solution (meaning it doesn't throw an
exception) is:

typeof window.frameElement == 'undefined'

AFAIK, that's how it sits today; never mind that it will never be true
in IE.

On the other hand, this condition blows up:

!window.frameElement

A host property in IE that throws exceptions on type conversion. Now
where have I seen that before? Oh yeah, getAttribute.

http://ejohn.org/blog/future-proofing-javascript-libraries/#postcomment

Apparently he still can't debug scripts in IE (or use the alert
method.) And since when is it a solution to replace something that
works sporadically with something that can never work?

Note to the Ninja: recreate one of your "edge cases" and do this:

window.alert(typeof window.frameElement);

I'll go way out on a limb and suggest the result will be "unknown."
Sad commentary that handling the load event in jQuery means dealing
with IE's behind-the-scenes ActiveX machinations. Even sadder that
the jQuery developers are so ill-equipped to handle them.

This is why jQuery will never be more than a bad joke. Resig knows
virtually nothing about IE and refuses to learn (preferring to post
blog entries full of fantastic assumptions.) The punchline is that so
much of the browser-challenged population insists on defending his
bullshit while at the same time wasting time asking for help in his
forums. How many times can they write "I just love jQuery, but..."
without noticing that their sentiments are misplaced.

In the comments, several of library luminaries of the day discuss
feature detection. This is the Ninja talking to the MacGyver:

"I can't imagine most libraries being able to withstand a DOM-
compliant IE 8 (assuming that it has its own set of bugs and
misgivings - and that libraries weren't able to adapt)."

Prophetic in so many ways. Of course, none are at all kind to
*him*. :)

I can't imagine somebody this ignorant and lazy becoming anything more
than a laughingstock. I guess if you pump enough Spam through Twitter
and have your face on a favicon, anything can happen.

History will sort it out. For now, ignore the buffoons with the funny
nicknames. Nothing they say or do will impact the future of Web
development in any meaningful way. Look what they are using to
communicate with each other. As with Ajaxian, the comments are
illegible. These guys need to start thinking about "today’s
problems" before addressing the future.
 
D

David Mark

I had hoped my article would have had some influence and people would
no longer be interested in when the document is "ready" sometime
before window.onload. It is not ready when it is claimed to be
"ready".

You were right as rain. Hope springs eternal that others will
notice. But then, you don't Spam Twitter do you? That's where the
twits get their information.
 http://peter.michaux.ca/articles/the-window-onload-problem-still

Even if it was ready when it is "ready", it would still leave elements
exposed for a short time without being enlivened.

That depends on the design.
I think that the
approach of using document.ready  will never be a true solution even
if an implementation is bug free.

It's not needed, often abused and is the lynch-pin of "Unobtrusive
Javascript." What a joke those two words have become.
on* HTML attributes or delegate listeners are both true solutions.

Typically I use the onload attribute of the body and occasionally
onsubmit for simple form validation. Other than that, I say hide
interactive elements until they are ready for use. Delegation is
useful, but I don't see how it fits into this puzzle.
I think what is happening is that some people try to believe certain
things work, or can work, or will work just because that is the way
they want things to work.

Cognitive dissonance plays a part. The primary rationalization here
is that these miserable "unobtrusive" libraries will ultimately save
them time. :)
David, my question to you is why are you reading the jQuery list?

Why not? I bookmark the worst offenders as I get emails from people
looking for ammunition to use against deluded time-wasters in adjacent
cubes. That group is an endless supply (as is Resig's endless
blogging buffoonery.) Additionally, I think a compilation would make
a great book. "Clods' Letters to jQuery" or... "How the Web was
Lost."
 
P

Peter Michaux

Delegation is
useful, but I don't see how it fits into this puzzle.

One common use of unobtrusive JavaScript is to attach "click" handlers
to elements of interest in the page as soon as possible. The "as soon
as possible" usually means that the element is visible for a short, or
maybe long, time before the handler is attached. That is bad.

By using global delegation, the click handler can be attached to
something that already exists when the document head loads: e.g. the
documentElement. Then the click events on those elements of interest
bubble up to the documentElement and can be handled there. This means
the elements of interest were never simultaneously visible and
unenlivened in the page.

I experimented with this sort of global delegation quite a bit. Wrote
a library that was kind of neat to enable handlers to be specified
with CSS selectors. One very nice feature of global delegation is that
widgets HTML can be added to the page and the delegation just works.
Global delegation works but in the end I didn't think the style of
programming that seems to be natural with this sort of global
delegation was a very nice/the best style of browser scripting.

Peter
 
D

David Mark

One common use of unobtrusive JavaScript is to attach "click" handlers
to elements of interest in the page as soon as possible. The "as soon
as possible" usually means that the element is visible for a short, or
maybe long, time before the handler is attached. That is bad.

Right, unless the developers realize this and hide them until the DOM
is ready.
By using global delegation, the click handler can be attached to
something that already exists when the document head loads: e.g. the
documentElement. Then the click events on those elements of interest
bubble up to the documentElement and can be handled there. This means
the elements of interest were never simultaneously visible and
unenlivened in the page.

I see, but I wouldn't attach listeners to anything before the DOM is
ready.
I experimented with this sort of global delegation quite a bit. Wrote
a library that was kind of neat to enable handlers to be specified
with CSS selectors. One very nice feature of global delegation is that
widgets HTML can be added to the page and the delegation just works.
Global delegation works but in the end I didn't think the style of
programming that seems to be natural with this sort of global
delegation was a very nice/the best style of browser scripting.

I agree. Seems like an end-around.
 
S

SAM

Le 6/24/09 6:53 AM, David Mark a écrit :
Right, unless the developers realize this and hide them until the DOM
is ready.

How do you realize that ?

head
styles
JS
document.style.visibility = 'hidden';
onload = function() { document.style.visibility = 'visible';}
body
div

???
 
D

David Mark

Le 6/24/09 6:53 AM, David Mark a écrit :



How do you realize that ?

What is it you don't understand?
head
    styles
    JS
       document.style.visibility = 'hidden';
       onload = function() { document.style.visibility = 'visible';}
body
    div

???

Nope. For example, consider a document with a link that will
ultimately be scripted to display a DIV (as opposed to navigating to
another document or fragment.) What you want to avoid is having one
behavior during the load and another afterward (very confusing for the
users.) You could say to hell with "Unobtrusive Javascript" and use
an onclick attribute (only recommended for very simple applications.)
Or you could add a visibility:hidden rule to the head once you detect
the features required to display the DIV. Override this rule once the
document is loaded and the click listener is attached.

In an HTML DOM, this is a rare case where it is reasonable (and even
preferable) to use document.write. If you can't stomach
document.write, move your script to the body (prior to the link of
course) and append the rule (but remember there is no guarantee the
DOM will react kindly to mutation during loading.)
 
S

SAM

Le 6/24/09 10:36 AM, David Mark a écrit :
What is it you don't understand?

How do you hide a div using JS and before the navigator parses this
div's html code.
(that's to say : the JS doesn't know the div to hide it).
For example, consider a document with a link that will
ultimately be scripted to display a DIV (as opposed to navigating to
another document or fragment.)

Yes, it is exactly that (a simple case).
What you want to avoid is having one behavior during the load and
another afterward (very confusing for the users.)

Yes again.
You could say to hell with "Unobtrusive Javascript" and use
an onclick attribute (only recommended for very simple applications.)
Or you could add a visibility:hidden rule to the head once you detect
the features required to display the DIV. Override this rule once the
document is loaded and the click listener is attached.

I do not like that at all
(scripts JS in body)

I thought you could give me an idea how to do from the head.
(a very very simple way to do it, if possible)
 
D

David Mark

Le 6/24/09 10:36 AM, David Mark a écrit :



How do you hide a div using JS and before the navigator parses this
div's html code.
(that's to say : the JS doesn't know the div to hide it).


Yes, it is exactly that (a simple case).


Yes again.


I do not like that at all
(scripts JS in body)

Read it again. That was the second (and less preferred) option.
I thought you could give me an idea how to do from the head.
(a very very simple way to do it, if possible)

As mentioned, document.write.
 
T

Thomas 'PointedEars' Lahn

kangax said:
[...]
I have been using this approach for a while as well and it's been
working fine so far. I actually mentioned it here recently in a
conversation with D. Mark:
<http://groups.google.com/group/comp.lang.javascript/msg/518d3c8817cdb24a>

PointedEars then expressed concerns about potential problems with this
approach:

<cite>
Proprietary DOM implementations may not consider the root element an
event target for an event, and AIUI even standards-compliant DOM
implementations do not need to. Insofar the "weirdness" of this
approach constitutes an argument against it.

<http://www.w3.org/TR/DOM-Level-3-Events/events.html#Events-EventTypes...>
</cite>

To date, I haven't seen a browser that doesn't consider
`documentElement` an EventTarget, though.

Look further. In any case, in an (X)HTML document it is not only
unnecessarily unreliable (as pointed out), but also unnecessarily
inefficient to let every bubbling event bubble up to the root
element node; for most cases it suffices and is more efficient
to use the body element node or a closer ancestor of the target
element instead.


PointedEars
 
T

Thomas 'PointedEars' Lahn

David said:
Right, unless the developers realize this and hide them until the DOM is
ready.

Your idea is good, but it is not going to work. In order to use CSS
scripting for hiding an element, you need to be sure that the element object
is there (i.e., that "the DOM is ready"). You cannot be sure that the
element object is there before the `load' event of the `body' element
occurs, and an infinite time may have passed in which the user may have
created any event. (JFTR: That is not to say that "Unobtrusive JavaScript"
would be any better.)

And I thought we have agreed to that hiding elements by default instead
(that is, with the default CSS rules) is a bad idea.
I see, but I wouldn't attach listeners to anything before the DOM is
ready.

I go a step further and do not add event listeners dynamically if it is not
not necessary in the first place.


PointedEars
 
D

David Mark

Your idea is good, but it is not going to work.  In order to use CSS

Been working for me for a long time.
scripting for hiding an element, you need to be sure that the element object

I think you misunderstand. I can add any style rule I want. What
difference could it make if the anticipated elements haven't been
parsed yet?
is there (i.e., that "the DOM is ready").  You cannot be sure that the
element object is there before the `load' event of the `body' element
occurs, and an infinite time may have passed in which the user may have
created any event.  (JFTR: That is not to say that "Unobtrusive JavaScript"
would be any better.)

And I thought we have agreed to that hiding elements by default instead
(that is, with the default CSS rules) is a bad idea.

It is if the rule is part of static CSS. The idea (which has been
realized many times) is to add the rule(s) with script, and after the
required features have been detected.
I go a step further and do not add event listeners dynamically if it is not
not necessary in the first place.

I find that it is preferable for most applications. There are
exceptions. Regardless, the body onload attribute should always be
used. Nothing wrong with adding a DOMContentLoaded listener in
addition, provided you understand all of the issues involved (e.g.
listener will be called twice in some agents, later in IE, etc.)
 
T

Thomas 'PointedEars' Lahn

David said:
Been working for me for a long time.


I think you misunderstand. I can add any style rule I want. What
difference could it make if the anticipated elements haven't been
parsed yet?

Ah, dynamically added style rules. I hadn't thought of that.
[...]
I go a step further and do not add event listeners dynamically if it is not
not necessary in the first place.

I find that it is preferable for most applications. There are
exceptions. Regardless, the body onload attribute should always be
used.
ACK

Nothing wrong with adding a DOMContentLoaded listener in addition,

What for?


PointedEars
 
P

Peter Michaux

consider a document with a link that will
ultimately be scripted to display a DIV (as opposed to navigating to
another document or fragment.) What you want to avoid is having one
behavior during the load and another afterward (very confusing for the
users.) You could say to hell with "Unobtrusive Javascript" and use
an onclick attribute (only recommended for very simple applications.)
Or you could add a visibility:hidden rule to the head once you detect
the features required to display the DIV. Override this rule once the
document is loaded and the click listener is attached.

In an HTML DOM, this is a rare case where it is reasonable (and even
preferable) to use document.write. If you can't stomach
document.write, move your script to the body (prior to the link of
course) and append the rule (but remember there is no guarantee the
DOM will react kindly to mutation during loading.)

For this situation, it seems to me that document.write is a good way
to write a little bit of style into the page rather than trying to
append a style elements to the page with the DOM methods while it
loads. I think that here I'd prefer document.write to any other
technique.

Why do you suggest moving the script to the body in order to append a
style element to the document? The style rule should be appended to
the head, shouldn't it? Are you just trying to ensure that at least
the head is completely loaded before appending to it? I think this
would reduce the risk or trouble. (I still think document.write is
probably better.)

Peter
 
D

David Mark

Been working for me for a long time.
I think you misunderstand.  I can add any style rule I want.  What
difference could it make if the anticipated elements haven't been
parsed yet?

Ah, dynamically added style rules.  I hadn't thought of that.
[...]
By using global delegation, the click handler can be attached to
something that already exists when the document head loads: e.g. the
documentElement. Then the click events on those elements of interest
bubble up to the documentElement and can be handled there. This means
the elements of interest were never simultaneously visible and
unenlivened in the page.
I see, but I wouldn't attach listeners to anything before the DOM is
ready.
I go a step further and do not add event listeners dynamically if it is not
not necessary in the first place.
I find that it is preferable for most applications.  There are
exceptions.  Regardless, the body onload attribute should always be
used.
ACK

Nothing wrong with adding a DOMContentLoaded listener in addition,

So agents that support that event can run my initialization while the
images and other assets are loading.
 
P

Peter Michaux

On Jun 24, 5:02 am, SAM <[email protected]>
wrote:

As mentioned, document.write.

I believe David is suggesting something vaguely like the following in
the head of the document.

<script type="text/javascript">

if (feature tests for showing the div pass) {
document.write('<style type="text/css">#magicDiv
{visibility:hidden;}<\/style>');
window.onload = function() {
document.getElementById('magicDiv').style.visibility =
'visible';
};
}

</script>

The important part is before the document.write is used to hide the
magicDiv, you need to know that you will be able to unhide it later.
Perhaps checking that the documentElement.style.visibility property is
a string type is sufficient to think it will be possible to unhide it
when the page has loaded.

Peter
 
P

Peter Michaux

So agents that support that event can run my initialization while the
images and other assets are loading.

There is an assumption here that when DOMContentLoaded fires, the
document is not just loaded but also ready to be mutated. That may be
an acceptable assumption though a de facto standard.

Peter
 
D

David Mark

There is an assumption here that when DOMContentLoaded fires, the
document is not just loaded but also ready to be mutated. That may be
an acceptable assumption though a de facto standard.

Yes, it is only a de facto standard. I'm fine with that one.
 
P

Peter Michaux

I have been using this approach for a while as well and it's been
working fine so far. I actually mentioned it here recently in a
conversation with D. Mark:
<http://groups.google.com/group/comp.lang.javascript/msg/518d3c8817cdb24a>

PointedEars then expressed concerns about potential problems with this
approach:

<cite>
Proprietary DOM implementations may not consider the root element an
event target for an event, and AIUI even standards-compliant DOM
implementations do not need to. Insofar the "weirdness" of this
approach constitutes an argument against it.

Just because David finds the technique "odd" and Pointy Ears finds it
"weird", that doesn't mean it is a flawed approach. For example, a lot
of Perl programmers think using lambdas and proper tail calls odd or
weird just because it isn't common to see them used in Perl code but
Perl does in fact have both and they can be useful.
<http://www.w3.org/TR/DOM-Level-3-Events/events.html#Events-EventTypes...>
</cite>

To date, I haven't seen a browser that doesn't consider
`documentElement` an EventTarget, though.


Could you expand on this?

One real problem is non-bubbling events like focus. I made a stab at
addressing this issue

http://peter.michaux.ca/articles/the-window-onload-problem-really-solved

All events go thorough the capture phase so if IE supported the DOM3
event module capture could be used for non-bubbling events. IE doesn't
so capture is out as an option.

Another problem is what do you do if an event bubbles up to the global
handler while the DOM is still loading? Sure you have the event but if
the handler is intended to mutate the document, is it really safe to
mutate the document at that time? Should you put the event in some
queue to handle when window.onload eventually fires?
Why do you not find this style nice and which
style do you find the best?

That is a wide-open-ended question. I suppose it depends on the
circumstance. Usually I just enliven the elements in the page when the
window.onload event fires.

Peter
 

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

Latest Threads

Top