preferred way of handling events

S

Stanimir Stamenkov

Sat, 14 Aug 2010 13:20:42 -0700 (PDT), /David Mark/:
Being implemented in all of the "major browsers" is hardly a ringing
endorsement. Assume it is implemented in as many browsers as support
the onload attribute of the body (likely a bad assumption). Then you
could either flip a coin or go with the choice that is backed by a
standard. Which makes more sense?

By the way, may of the current W3C Recommendations / "standards"
have been pushed long ago without having at least two conforming
implementations, so they are effectively non-standards, now. I can
count better on the currently developing versions of the
corresponding standards, rather than on those which are currently
marked as Recommendations.
 
D

David Mark

Sat, 14 Aug 2010 13:20:42 -0700 (PDT), /David Mark/:








I guess you miss the point.

You guess wrong.
Being implemented for long time and
then having a standardization effort for it guarantees one can count
on it.

The window.onload property has not been implemented longer than the
onload attribute of the body.
I think you're ignoring the standards development lightly.

Standards will always evolve so if you always wait for them to be
signed off then it is not guaranteed how long they will stay
unchanged.

Who is waiting? The body onload attribute has been around since the
90's.
On the other hand if you watch the development of the
standard more closely you'll have a better idea on where they are
headed and what you could count on.

Where they are headed doesn't do a thing for me right now.
 
D

David Mark

Sat, 14 Aug 2010 13:20:42 -0700 (PDT), /David Mark/:


By the way, may of the current W3C Recommendations / "standards"
have been pushed long ago without having at least two conforming
implementations, so they are effectively non-standards, now.  I can
count better on the currently developing versions of the
corresponding standards, rather than on those which are currently
marked as Recommendations.

You can count on something that didn't exist when the majority of the
browsers in use today were developed? That doesn't make any sense.
 
D

David Mark

It doesn't, of course, but that wasn't the point. We're talking about
two different ways to set up a handler for the "load" event - one of
them is defined by the HTML standard, the other falls into an completely
different area which has never been officially standardized, but is
nevertheless heavily used and well supported.

And shouldn't that be the end of the discussion?
Both have their minor pros
and cons, and I'm trying to understand why you and Thomas think that one
is superior to the other.

I think you said it fine yourself (above).
The lack of a standard would have been an
argument in your favor if you didn't already use the same unstandardized
mechanism (DOM-0 events in scripts) in other places.

I think you'll find that I avoid attaching listeners to the window
object whenever possible. The most critical listener (load) is the
last one I would trust to the window object. Unlike documents and
elements, there is no standard for the window object. That's why -
for example - some browsers feature document.addEventListener, but not
window.addEventListener.
Another way to answer your question is that a de-facto standard will
beat an official standard any day if it better reflects the way things
actually are.

But it doesn't in this case.
But this line of arguing is going to get me bashed as an
evil "pragmatist", which I would find humorous, but isn't the direction
I'd like this discussion to go ;)

Yeah, the most recent exhortation to "be pragmatic" I read came from
Thomas Fuchs. He was advocating CSS parse hacks over IE conditional
comments. And, of course, the Dojo authors use that word a lot. Bad
company.
One possible reason is that many developers dislike mixing logic and
presentation.

To the extent that *one* attribute on the body is a deal-breaker?
That's the sort of silliness that I associate with the "unobtrusive
Javascript" movement. There are other examples as well. If a script
will only ever be associated with a single document (and the two are
typically changed in tandem), it makes no sense to put that script in
a separate file, except in some blind rush to be "unobtrusive". It's
cargo cult behavior; chanting buzzwords instead of thinking.
The three typical (textual) components of a document -
HTML, CSS, and scripts - are complimentary, and they each have a
different focus:

   HTML - structure and content
   CSS  - design (usually visual)
   JS   - additional functionality and interactivity

Yes and there are exceptions to the "rule" that says they must all
reside in separate files.

As a related note, I see a lot of frameworks (e.g. Dojo) that
incessantly break up every feature into the separate files. I once
asked the Dojo developers why they did that, seeing as the "base" Dojo
build invariably requires about a dozen of them (requiring developers
to wait for twelve synchronous XHR requests each time they refresh).
Their "answer" was that it was the only "sane" way to do things. :)
People who are used to working with templates will tend to avoid
inserting too much logic (JS) into the template (HTML).

One attribute?

onload="if (typeof bodyLoad == 'function') { bodyLoad() }"

Works whether they create a bodyLoad function or not. The trouble is
that many developers will see such a thing as "ugly" (as if aesthetics
trump logic). Of course, many developers are in the wrong business.
Keeping them
separate makes maintainance easier: you don't have to look all over the
place to find out which scripts work together, or where events may be
triggered.

How is it any easier to find a script in another file than in the
document itself? If you are referring to documents with tons of event
handler attributes, I am certainly not advocating anything like that.
You seem to use "unobtrusive" as a kind of epithet (like "pragmatic"),

Look how those words are thrown around and used to justify bad
decisions.
but there is a reason why developers are finding this type of design
appealing, and it's not just because of some new buzzword.

Most Web Developers desperately want absolute rules as they don't
require any thinking. If you start questioning the rules they've
built up, it makes them go ballistic. Buzzwords are their rallying
cries. Am I just being harsh or are the majority of Web developers
irretrievably ignorant and incompetent?
I realize that it's not practical to keep them completely separate all
the time, especially when doing so would mean adding awkward and
unnecessary code.

Right. Or extra http requests.
I use onclick in anchors and buttons quite a lot,

In some contexts it makes sense.
I
add ids and classes to my HTML elements which have nothing to do with
the document's structure,

I don't use classes for anything but CSS. Of course, ID's often are
often dual-purpose (for styling and scripting). But I don't see how
any of that relates to the document's structure (other than the
presence of the attributes).
and I use inline CSS in some plaves.

As in style attributes? Those I avoid entirely. Inline style blocks
are fine though (assuming they are only relevant to a single
document).
There are
many exceptions. The onload attribute might just be one. However, I'm
still not convinced that it has any real advantages over window.onload.

Still? :)
For you and me, sure. Most people have never heard of them. Some of them
 edit our stuff after we leave. Best not to give them any bad ideas.

I document my stuff before I leave; that way there are no
misunderstandings (unless future developers fail to read the
documentation). There's only so much you can do though. I once
revisited a project to find that a simple form validation I wrote had
been littered with dojo.query calls and at least one line that blew up
in IE7 (and IE8 compatibility mode). When I asked about this, I was
told that using the elements collection of forms was "old fashioned",
queries were "more concise" (despite requiring the behemoth Dojo
library) and testing "ancient browsers" like IE7 was a "waste of
time". Thankfully management sided with me on that one.
Of course, that was a contrived example to illustrate the point.

When it comes to making points, I prefer less contrived examples.
Shouldn't be a problem, because you're rarely going to have both.

More like you are never going to have both because one cancels out the
other. If you avoid window.onload, you avoid that problem. It's much
easier to tell at a glance if a document runs a script on load by
looking at the body element. Wading though extraneous "unobtrusive"
scripts to find window.onload assignments is far more trouble.
Like everything else we add to the 'window' object. I don't see a
problem with that.

It's just an example of a side effect.
In this case, it may even be beneficial, because now
we have a reference for our event handler.

How does that help?
To be quite honest, I never
thought of checking if the 'window' object already had an onload
property before one is set explicitly.

You have to when lots of "unobtrusive" scripts are mashed together (as
is often the case on the Web). You end up with a daisy-chain of
calls. Wouldn't it be much simpler to have an array of functions that
are called by a "bodyLoad" function that is "attached" with an event
handler attribute.
In any case, this is unlikely to
cause trouble.

What is unlikely to cause trouble? If you step on an existing
window.onload property, that's likely to be big trouble.
See above for my thoughts about "unobtrusive" code and a possible reason
why window.onload may be preferable.

See above for my responses. :)
 
G

Garrett Smith

Garrett said:
Thomas said:
[...] multiple event listeners for the same event and object can be
accomplished using proprietary event-handler properties ("'on' event
properties") as well, using a user-defined event registry (method; like
jsx.dom.addEventListener()).

The way to maintain order for IE is to create an abstraction that keeps
an array and adds a callback to the object. One way to add that callback
is to use DOM 0 event handler property.
Yes.

Another way is to use attachEvent.

No, apparently you have not paid attention.

Think about it.

It is possible to add a callback (just one) using attachEvent and that
callback call an array of callbacks?

Proprietary event-handler properties are not the only way to guarantee
in the MSHTML DOM.
If one callback is added with attachEvent and that callback is an
adapter for all other callbacks, then the order within that callback
could be guaranteed by the program.
[...]
I have two registries: one that uses event handler properties and one
that uses attachEvent/addEventListener. Each registry has the same
interface so they can be swapped out for one another.

There is no advantage in using attachEvent(), and there are several
disadvantages. Your approach is not logical.
An event handler added by attachEvent cannot be replaced or removed by
another script if that other script can't get access to that dispatching
function.
 
T

Thomas 'PointedEars' Lahn

Garrett said:
Thomas said:
Garrett said:
Thomas 'PointedEars' Lahn wrote:
[...] multiple event listeners for the same event and object can be
accomplished using proprietary event-handler properties ("'on' event
properties") as well, using a user-defined event registry (method; like
jsx.dom.addEventListener()).

The way to maintain order for IE is to create an abstraction that keeps
an array and adds a callback to the object. One way to add that callback
is to use DOM 0 event handler property.
Yes.

Another way is to use attachEvent.

No, apparently you have not paid attention.

Think about it.

It is possible to add a callback (just one) using attachEvent and that
callback call an array of callbacks?

Of course it is possible. But that would not prevent arbitrary order of
execution of the event listener already added to the element through an
event-handler attribute or property and the event listener that "calls an
array of callbacks". Using only event-handler properties as a fallback to
addEventListener() (for non-capturing listeners) does.
Proprietary event-handler properties are not the only way to guarantee
in the MSHTML DOM.

attachEvent() certainly is not. So what alternatives do you have in mind?
If one callback is added with attachEvent and that callback is an
adapter for all other callbacks, then the order within that callback
could be guaranteed by the program.
[...]
I have two registries: one that uses event handler properties and one
that uses attachEvent/addEventListener. Each registry has the same
interface so they can be swapped out for one another.

There is no advantage in using attachEvent(), and there are several
disadvantages. Your approach is not logical.

An event handler added by attachEvent cannot be replaced or removed by
another script if that other script can't get access to that dispatching
function.

That feature which might turn out to be a small advantage depends on the
implementation of that dispatching function, and it does not outweigh the
disadvantages of using attachEvent().

See also:
<http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html>


PointedEars
 
T

Thomas 'PointedEars' Lahn

Stefan said:
It doesn't, of course, but that wasn't the point. We're talking about
two different ways to set up a handler for the "load" event - one of
them is defined by the HTML standard, the other falls into an completely
different area which has never been officially standardized, but is
nevertheless heavily used and well supported.

No, we are talking about two different ways to add an event listener to two
*different* objects, which might or might not work the same; of which one
(the event-handler attribute) definitely has the longer history and a
(better) definition (per HTML 4.01 and W3C DOM Level 2+ Events), is thus
better supported, more interoperable, better suited to the task (of
determining when the *document* has been loaded), and so to be used.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Stanimir said:
Sat, 14 Aug 2010 13:20:42 -0700 (PDT), /David Mark/:

By the way, may of the current W3C Recommendations / "standards"
have been pushed long ago without having at least two conforming
implementations, so they are effectively non-standards, now.

Rubbish.


PointedEars
 
G

Garrett Smith

Garrett said:
Thomas said:
Garrett Smith wrote:
Thomas 'PointedEars' Lahn wrote:
[...] multiple event listeners for the same event and object can be
accomplished using proprietary event-handler properties ("'on' event
properties") as well, using a user-defined event registry (method; like
jsx.dom.addEventListener()).

The way to maintain order for IE is to create an abstraction that keeps
an array and adds a callback to the object. One way to add that callback
is to use DOM 0 event handler property.

Yes.

Another way is to use attachEvent.

No, apparently you have not paid attention.

Think about it.

It is possible to add a callback (just one) using attachEvent and that
callback call an array of callbacks?

Of course it is possible. But that would not prevent arbitrary order of
execution of the event listener already added to the element through an
event-handler attribute or property and the event listener that "calls an
array of callbacks". Using only event-handler properties as a fallback to
addEventListener() (for non-capturing listeners) does.

And if the registry uses event handler properties, that does not prevent
another piece of code from calling attachEvent. So I fail to see how
event handler properties solves this problem of other code using
`attachEvent` to add additional event handlers to the object.
attachEvent() certainly is not. So what alternatives do you have in mind?

`attachEvent` was what I was getting at.
That feature which might turn out to be a small advantage depends on the
implementation of that dispatching function, and it does not outweigh the
disadvantages of using attachEvent().

Designing the app so that the order of callbacks matters seems like a
mistake and so callbacks firing out of order has never been an issue for
me (because it wouldn't matter).

Since I have two registries, if they're both adding a callback to
document, then they're going to be stealing that event handler back and
forth.
 
G

Garrett Smith

It doesn't, of course, but that wasn't the point. We're talking about
two different ways to set up a handler for the "load" event - one of
them is defined by the HTML standard, the other falls into an completely
different area which has never been officially standardized, but is
nevertheless heavily used and well supported. Both have their minor pros
and cons, and I'm trying to understand why you and Thomas think that one
is superior to the other. The lack of a standard would have been an
argument in your favor if you didn't already use the same unstandardized
mechanism (DOM-0 events in scripts) in other places.

Another way to answer your question is that a de-facto standard will
beat an official standard any day if it better reflects the way things
actually are. But this line of arguing is going to get me bashed as an
evil "pragmatist", which I would find humorous, but isn't the direction
I'd like this discussion to go ;)


One possible reason is that many developers dislike mixing logic and
presentation.

Another possibility is that there's a piece of code that is not related
to the HTML and that the HTML BODY element doesn't have anything to do
with that particular piece of JS code.

If a server side templating system is used then a generic onload handler
can be added:

<body onload="doBodyOnload()"

But then you need to go and define what `doBodyOnload` does and if it is
calling multiple unrelated functions, then you may want to contend with
the issue of managing the possibility failure of any one of those
functions, which, being unrelated, should not affect each other.

And if you already have a registry that calls the callbacks in a
try/catch, then you can either duplicate that logic in your BODY onload
handler or make an exception here and let unrelated callbacks affect
each other.

Any browser coming out that supports javascript but not window.onload
would find itself running in so few pages as to call the browser broken.
Though whether or not it is the "most important event" for the masses of
amateur web pages I can't say for sure.

For me it's certainly not that important; I hardly ever use it.
Ironically, I mostly want it for IFRAMEs, which is a place that it kind
of sucks at.
 
G

Garrett Smith

[...]
attachEvent() certainly is not. So what alternatives do you have in mind?

[...]

Another benefit:
I was just reminded about the `onload` problem with IFRAME. That is, in
IE, assigning a function to an IFRAME's `onload` property won't resulti
n that function being called when the IFRAME is loaded. However, if the
function is added with `attachEvent`, it will fire.
 
T

Thomas 'PointedEars' Lahn

Garrett said:
And if the registry uses event handler properties, that does not prevent
another piece of code from calling attachEvent. So I fail to see how
event handler properties solves this problem of other code using
`attachEvent` to add additional event handlers to the object.

attachEvent() is in my experience not used as much by third-party code as
event-handler properties are. It also does not appear to be known by as
many people writing client-side scripts, and it is likely to be deprecated
when and if Microsoft finally decides (as the last player on the court) to
be standards-compliant with their event model.

However, if that method is used by third-party code, then it is the people
using it who, if the outcome of that turns out to be undesirable, can
correct their approach. Using attachEvent() in my code in the first place
would be a hindrance to using my code, and it would reduce the efficiency of
my code, instead.
`attachEvent` was what I was getting at.

Then apparently you have not thought this through.
Designing the app so that the order of callbacks matters seems like a
mistake
IBTD.

and so callbacks firing out of order has never been an issue for
me (because it wouldn't matter).

If you want your code to be used by other people, such as in a script
library, you should assume that it is.
Since I have two registries, if they're both adding a callback to
document, then they're going to be stealing that event handler back and
forth.

Your logic is flawed.


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
september.org>, Sun, 15 Aug 2010 00:37:55, Garrett Smith
I was just reminded about the `onload` problem with IFRAME. That is, in
IE, assigning a function to an IFRAME's `onload` property won't resulti
n that function being called when the IFRAME is loaded. However, if the
function is added with `attachEvent`, it will fire.


I needed to be reminded to ask about that. It was, in essence, said
here a few weeks or months ago, with somewhat more detail. But, when I
fitted it into a page, it did not work. Evidently there was an error in
the description or its use.

Just how should this be changed and added to in order to work in IE FF
etc. without TimeOut?


function StartJob() { // sitedata
Initialise()
TimeOut = +Form.Tout.value
Ifr.onload = TimeOut ? DummyF : ReadStatsFile
Ifr.src = Form.DatF.value.trim()
if (TimeOut) setTimeout(ReadStatsFile, TimeOut) }


function ReadStatsFile() { var FILE
Ifr.onload = DummyF
FILE = Ifr.contentDocument.body
FILE = FILE.textContent || FILE.innerText // IE8 needs latter
ShowStatsFile(FILE) } // <- does all the work
 
G

Garrett Smith

In comp.lang.javascript message<[email protected]
september.org>, Sun, 15 Aug 2010 00:37:55, Garrett Smith



I needed to be reminded to ask about that. It was, in essence, said
here a few weeks or months ago, with somewhat more detail. But, when I
fitted it into a page, it did not work. Evidently there was an error in
the description or its use.

Just how should this be changed and added to in order to work in IE FF
etc. without TimeOut?

Using setTimeout is setting up a race condition. setInterval would be
safer and allow for faster results. Though nonstandard, the "load" event
on the iframe can be listened for. This functionality is codified in the
HTML draft[1].

For IE, you can use `attachEvent` to listen for "onload". Do this just
prior to setting the IFRAME's `src`.

iframe.attachEvent("onload", iframeLoaded);
iframe.src = location.href + "#testing";

For Gecko, you can use `addEventListener`, which requires that the "on"
part of the event name be removed.

iframe.addEventListener("load", iframeLoaded, false);

Put the two together in a function that abstracts that.

I've just tested for local files and load handler seems to work as well.

So where you have:
Ifr.onload = TimeOut ? DummyF : ReadStatsFile

You can use instead:
addCallback(Ifr, "load", ReadStatsFile);

where addCallback does either attachEvent or addEventListener.

Something like:

// Untested
function addCallback(obj, type, callback) {
// First try standard event model (some browsers have both models).
if(obj.addEventListener) {
obj.addEventListener(type, callback, false);
} else {
obj.attachEvent("on" + type, callback);
}
}

Now with that, keep in mind that there will be significant differences
that are unresolved. The `this` value of the callback will vary and in
MSIE, it will always be the global object. For an iframe load event, the
event parameter passed to the callback function will be either something
of a DOM "load" event or an IE "load" event. Again, as stated, this
event is not standard and so no assertions for "correct" behavior can be
made. Also as stated earlier, the order of callbacks can vary in IE.

// Callbacks fire out of order in MSIE
var i, funBody;
for(var i = 0; i < 10; i++) {
var funBody = "alert(['i:'+" + i + ",'this:' + this.nodeName])",
fun = new Function(funBody);
addCallback(document, "click", fun );
}

Now in MSIE that I've tested, I get the callbacks firing as
"3,5,7,9,8,6,4,2,1,0" whereas in DOM browsers, I get 0-9 firing in order.

Although many sources state that `attachEvent` results in no parameter
being passed to the callback, this is simply not the case. In MSIE, the
callback does indeed get an event parameter when `attachEvent` is used.

[1]http://www.w3.org/TR/html5/the-iframe-element.html#the-iframe-element
 
T

Thomas 'PointedEars' Lahn

Garrett said:
Thomas said:
attachEvent() is in my experience not used as much by third-party code as
event-handler properties are. It also does not appear to be known by as
many people writing client-side scripts, and it is likely to be
deprecated when and if Microsoft finally decides (as the last player on
the court) to be standards-compliant with their event model.

And so event handler properties do not stop any other code from calling
attachEvent any more than a registry that uses attachEvent. [...]

Of course not (I have explained this already), but then that is *their*
problem.
Why are you relying on callback order?

Why not?
Your logic is flawed.

Did you misunderstand? [...]

No. You have two event registries, which is unnecessary to begin with.
As a result, while your conclusions might be considered valid, they are
still based on a false premise.


PointedEars
 
G

Garrett Smith

[...]
Why are you relying on callback order?

Why not?

I haven't seen any good example of where it makes sense to rely on
callback order.

Wouldn't that make callbacks tightly coupled to each other?

Any subscriber concerned about ulterior side effects can more safely and
explicitly get notified from whatever method is causing them.
Since I have two registries, if they're both adding a callback to
document, then they're going to be stealing that event handler back and
forth.

Your logic is flawed.

Did you misunderstand? [...]

No. You have two event registries, which is unnecessary to begin with.
As a result, while your conclusions might be considered valid, they are
still based on a false premise.
Have you ever wanted to add delegated callback for focus events or an
onload event for IFRAME element?
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
september.org>, Mon, 16 Aug 2010 23:30:29, Garrett Smith
In comp.lang.javascript message<[email protected]
september.org>, Sun, 15 Aug 2010 00:37:55, Garrett Smith



I needed to be reminded to ask about that. It was, in essence, said
here a few weeks or months ago, with somewhat more detail. But, when I
fitted it into a page, it did not work. Evidently there was an error in
the description or its use.

Just how should this be changed and added to in order to work in IE FF
etc. without TimeOut?

Using setTimeout is setting up a race condition. setInterval would be
safer and allow for faster results. Though nonstandard, the "load"
event on the iframe can be listened for. This functionality is codified
in the HTML draft[1].

I have no intention of changing anything except as described above. As
the page, and others like it, read from a local file, the assigned
default timeout for IE will normally suffice.


For IE, you can use `attachEvent` to listen for "onload". Do this just
prior to setting the IFRAME's `src`.

iframe.attachEvent("onload", iframeLoaded);
iframe.src = location.href + "#testing";

For Gecko, you can use `addEventListener`, which requires that the "on"
part of the event name be removed.

But what uses Gecko? There should be a list of browsers and engines in
the FAQ I have to refer to www-use0.htm .


iframe.addEventListener("load", iframeLoaded, false);

Put the two together in a function that abstracts that.

I've just tested for local files and load handler seems to work as well.

So where you have:
Ifr.onload = TimeOut ? DummyF : ReadStatsFile

You can use instead:
addCallback(Ifr, "load", ReadStatsFile);

where addCallback does either attachEvent or addEventListener.

Something like:

// Untested
function addCallback(obj, type, callback) {
// First try standard event model (some browsers have both models).
if(obj.addEventListener) {
obj.addEventListener(type, callback, false);
} else {
obj.attachEvent("on" + type, callback);
}
}

Now with that, keep in mind that there will be significant differences
that are unresolved. The `this` value of the callback will vary and in
MSIE, it will always be the global object. For an iframe load event,
the event parameter passed to the callback function will be either
something of a DOM "load" event or an IE "load" event. Again, as
stated, this event is not standard and so no assertions for "correct"
behavior can be made. Also as stated earlier, the order of callbacks
can vary in IE.

The function works (IE, FF, Op, Sf, Cr); none of the rest is relevant.
The only need is to call it when its data will be available in the
iframe; it knows exactly what to do.


However, I did get the script into a state in which everything was
working EXCEPT for the value of this in a subsequent
<input type=button value="Count" onClick="Plot(this)">
and I don't know how I did that!.

Soon I should try to fit it to several other pages.

Thanks.
 

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
474,077
Messages
2,570,566
Members
47,202
Latest member
misc.

Latest Threads

Top