preferred way of handling events

G

Gerard Ketuma

So i have studied the DOM level 2 event handlers and have written some
nifty functions to take care of the browser incompatibilities with
this model. However, I feel like working with the traditional way of
handling events, where we assign functions to the event handler
property, is way easier and makes my code easy to follow. I know there
are all these benefits to using level 2 event handlers, like making
the code modular, making it easier for two or more people to handle
the same event. My question is, which of these models do you
frequently use? and why?
 
R

RobG

So i have studied the DOM level 2 event handlers and have written some
nifty functions to take care of the browser incompatibilities with
this model. However, I feel like working with the traditional way of
handling events, where we assign functions to the event handler
property, is way easier and makes my code easy to follow. I know there
are all these benefits to using level 2 event handlers, like making
the code modular, making it easier for two or more people to handle
the same event. My question is, which of these models do you
frequently use? and why?

There is no one way, it depends on the job.

Assigning a function reference to an "on" event property is fine where
an element only has one listener for that event (which is most of the
time). Where an element may have more than one listener for the same
event, then other schemes are required.
 
R

Richard Maher

Gerard Ketuma said:
So i have studied the DOM level 2 event handlers and have written some
nifty functions to take care of the browser incompatibilities with
this model. However, I feel like working with the traditional way of
handling events, where we assign functions to the event handler
property, is way easier and makes my code easy to follow. I know there
are all these benefits to using level 2 event handlers, like making
the code modular, making it easier for two or more people to handle
the same event. My question is, which of these models do you
frequently use? and why?

Personally, I don't think you can go past something along the lines of
David Mark's approach.

Cheers Richard Maher
 
G

Garrett Smith

There is no one way, it depends on the job.

Assigning a function reference to an "on" event property is fine where
an element only has one listener for that event (which is most of the
time). Where an element may have more than one listener for the same
event, then other schemes are required.
I like to use the approach of adding DOM 0 event handler properties when
the script generates the HTML code. In those cases, unrelated features
should not be accessing those elements anyway, and so should not care
about the event handlers.
 
G

Gerard Ketuma

There is no one way, it depends on the job.
Assigning a function reference to an "on" event property is fine where
an element only has one listener for that event (which is most of the
time). Where an element may have more than one listener for the same
event, then other schemes are required.

Thanks for all the input. makes sense
 
R

Ry Nohryb

There is no one way, it depends on the job.

Assigning a function reference to an "on" event property is fine where
an element only has one listener for that event (which is most of the
time). Where an element may have more than one listener for the same
event, then other schemes are required.

What I hate most about addEventListener is that you need to save a
reference to the handler f() if you ever want to remove it afterwards.
OTOH, on_xxx properties (DOM0 style) can be setup easily so as to
trigger more than a single handler.
 
R

Ry Nohryb

Jorge, could you elaborate on the "setup easily so as to trigger more
than a single handler?".

It's not that I have done it ever, I just meant that -I think- it
should be quite easy to do... :)
        window.onload = function() {

            var myDiv = document.getElementById("test");

            myDiv.onclick = function() {
                alert('foo');
            }

            var oldFn = myDiv.onclick;
            myDiv.onclick = function() {
                oldFn();
                alert('bar');
            }

            var oldFn2 = myDiv.onclick;
            myDiv.onclick = function() {
                oldFn2();
                alert('bletch');
            }

            var oldFn3 = myDiv.onclick;
            myDiv.onclick = function() {
                oldFn3();
                alert('blort');
            }

        }

...chains together handlers but requires a new reference for
each new handler.

Another attempt at it, (not very tested) could be:

function addHandler (elmnt, onWhat, newHndlr) {
var prevHndlr= elmnt[onWhat];
elmnt[onWhat]= (typeof prevHndlr === "function") ? function (event)
{
newHndlr.call(elmnt, event);
prevHndlr.call(elmnt, event);
} : newHndlr;
}

addHandler(window, "onclick", function(e){alert([this,e])});
addHandler(window, "onclick", function(){alert("The next alert should
show the 'this' and the event object")});
That doesn't seem any better than saving a ref for
each function added via addEventListener/attachEvent except that you
don't have to remove them one by one.

Yes, well, in order to remove it, when there's more than a handler
attached, one can't avoid the need to identify it, and for that one
needs to have saved a reference. But when there was only 1 I find it
much more convenient the DOM0 style of nulling the on_xxx property.
So I'm guessing there's a better
way to do it. Didn't discover it on a web search, though...

To do what exactly ? To manage more than a handler per event per
element ? In all truth, I very very rarely attach more than a single
handler.
 
T

Thomas 'PointedEars' Lahn

RobG said:
There is no one way, it depends on the job.

Full ACK.

Gerard: We have been over this ad nauseam. Please take heed of
Assigning a function reference to an "on" event property is fine where
an element only has one listener for that event (which is most of the
time). Where an element may have more than one listener for the same
event, then other schemes are required.

No, 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()).

In fact, that is the only way to guarantee in the MSHTML DOM that those
event listeners are executed in-order; EventTarget::addEventListener()
(which guarantees calls in order of listener registration) is not
implemented there, and attachEvent() disregards registration order (not to
mention its `this' problem).


PointedEars
 
T

Thomas 'PointedEars' Lahn

williamc said:
Jorge, could you elaborate on the "setup easily so as to trigger more
than a single handler?".

window.onload = function() {

JFTR: You want to avoid doing that specifically, regardless of the technique
used. Use the `onload' attribute of the `body' element instead.
var myDiv = document.getElementById("test");

myDiv.onclick = function() {
alert('foo');
}

var oldFn = myDiv.onclick;
myDiv.onclick = function() {
oldFn();
alert('bar');
}

var oldFn2 = myDiv.onclick;
myDiv.onclick = function() {
oldFn2();
alert('bletch');
}

var oldFn3 = myDiv.onclick;
myDiv.onclick = function() {
oldFn3();
alert('blort');
}

You should end each of those assignments with a semicolon, and it would be
better if you used less indentation when posting.
}

...chains together handlers ^^^^^^^^

but requires a new reference for each new handler.
^^^^^^^
_listener(s)_

Yes, but there is no real difference with the other approaches. You always
need a new reference (value), whether you store it in a variable or not.
That doesn't seem any better than saving a ref for each function added via
addEventListener/attachEvent except that you don't have to remove them one
by one.

You are not making sense.
So I'm guessing there's a better way to do it. Didn't discover it on a web
search, though...

Closures would allow you to automate the registration process in a method
where you would only need one extra variable. But, indeed, event listeners
are functions, and functions are also objects, so ...


PointedEars
 
D

David Mark

I've seen you mention this a number of times, and I'm curious: in what
way is <body onload="..."> superior to window.onload in a script
element?

One is backed up by a standard and one is not.
With the possible exception of ancient browsers, both appear to
have the exact same effect.

Assuming that such observations reflect reality in absolute terms
(always shaky ground in this business), you have a choice between a
standard and a non-standard (both seemingly identical). As all
browser developers must at least glance at the standards, it is a good
bet that a standard approach will be more widely supported.
I don't want to get into a debate about
"unobtrusive" scripts or other coding preferences, I would just like to
know if there's any practical difference between the two.

As for the "debates" about unobtrusiveness, they are about as useful
as any general argument in a discipline that is all about context.

I can't help but think of the Dojo contributor who dismissed my fix
for their "Operation Aborted" woes because advocating putting a script
element in the body would upset some unnamed "Unobtrusive Javascript
People". :)
 
G

Garrett Smith

Full ACK.

Gerard: We have been over this ad nauseam. Please take heed of


No, 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. Another way is to use attachEvent.
In fact, that is the only way to guarantee in the MSHTML DOM that those
event listeners are executed in-order; EventTarget::addEventListener()
(which guarantees calls in order of listener registration) is not
implemented there, and attachEvent() disregards registration order (not to
mention its `this' problem).
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.

It would still be possible for the code to go usurp your registry and go
directly to attachEvent and in so doing, cause indeterminate callback
firing order. However, that would also be true of DOM 0 event handler
properties.

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.
 
T

Thomas 'PointedEars' Lahn

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.
In fact, that is the only way to guarantee in the MSHTML DOM that those
event listeners are executed in-order; EventTarget::addEventListener()
(which guarantees calls in order of listener registration) is not
implemented there, and attachEvent() disregards registration order (not
to mention its `this' problem).

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.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Ry said:
Thomas said:
^^^^^^^
_listener(s)_

Q: What would you name the function that handles an event ?
A:
[ ] Listener
[x] Handler

(A+: PASS)

Perhaps that would happen in the School for Web Development Wannabes.

Wikipedia is not exactly known as a reliable source of information when it
comes to topics related to ECMAScript-based scripting. However, this
article does _not_ provide the confirmation that you sought. Indeed,

<http://en.wikipedia.org/wiki/Event_listener>

confirms what I have said. See also:

<http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-overview>
<http://www.w3.org/TR/DOM-Level-3-Events/#dom-event-architecture>


PointedEars
 
D

David Mark

Given the history of browser scripting, I wouldn't bet my life savings
on that...

Whether you would bet the farm on it is not a good test.
Generally, I agree that standards should be followed as far as possible.
In this case, however, the standard/non-standard distinction is a red
herring: the body's onload attribute is defined in the *HTML*
specification, which cannot possibly apply to DOM-0 event handling in a
script (window.onload, ele.onclick, etc).

It doesn't matter what specification defines it. The window object
has no standard specification at all.
AFAIK, this type of event
handling has never been officially standardized, but its age and its
almost ubiquitous support make it a de-facto standard.

And how would that trump the real HTML standard?
Both you and
Thomas have stated that you prefer the DOM-0 event model in certain
situations.
Yes.

If this model is used in your scripts anyway, what's the
harm in using it for onload as well?

For one, it is the most important of all events. And seeing as you
only need one attribute to handle it in standard fashion, why not add
it to the markup and be done with it?
The other events, for example
"click", have no standard DOM-0 definition either, but nobody would
think of recommending something silly like -

    ele.setAttribute("onclick", "someHandler()");

There are times when using an onclick handler in the markup makes more
sense than attaching it in any of the "unobtrusive" ways. For
example, if you only need one of them.
- which would be covered by a standard.

My argument is not simply standard vs. non-standard. Yes,
setAttribute is a standard, but over a decade of broken MSHTML
implementations has rendered it virtually useless.
I usually try to avoid inline event attributes, if only to prevent
unintentional effects due to their augmented scope.

Those are easy enough to avoid.
Especially in the
body element, where a document like this -

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
        <title>testing body attributes</title>
        <script type="text/javascript">
        var id = "A";
        </script>
    </head>
    <body onload="alert('onload:' + id)"

Obviously that's a red herring. All you would normally be doing here
is calling a (sensibly named) function that initializes your
enhancements.
          onclick="alert('onclick:' + id)"
          id="B">
    <p>BODY TEXT</p>
    </body>
    </html>

- will give different results in different browsers. Scope augmentation
isn't officially standardized, either, but it still exists and causes
problems on a regular basis. The DOM-0 event model doesn't have this
ambiguity.

The window.onload property has side effects as well. For one, it will
clobber any extant onload attribute of the body (in some observed
browsers). It will also add a global property called "onload".
There's just no reason to use it, except in an ill-advised attempt to
be 100% "unobtrusive".
 
R

Ry Nohryb

(...)
The window.onload property has side effects as well. (...)
It will also add a global property called "onload". (...)

Adding a property to a host object augments the global object ? How
so ? :)
 
D

David Mark

Adding a property to a host object augments the global object ? How
so ? :)

Yes. Host objects can do whatever they want. That includes mirroring
properties of the global object (including the reference to itself).
They can just as easily add them too. Why do you have trouble with
this?
 
D

David Mark

Fri, 13 Aug 2010 19:14:45 -0700 (PDT), /David Mark/:



What about the emerging HTML5 standard:

It's not a standard yet and will take years to be relevant. Just
ignore it for now.

Yes, they are finally trying to standardize the window object. It
won't be retroactive though. ;)
It also happens the given interface has been implemented in all
major browsers for quite some time now.

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?
 
S

Stanimir Stamenkov

Sat, 14 Aug 2010 13:20:42 -0700 (PDT), /David Mark/:
It's not a standard yet and will take years to be relevant. Just
ignore it for now.


Yes, they are finally trying to standardize the window object. It
won't be retroactive though. ;)


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?

I guess you miss the point. Being implemented for long time and
then having a standardization effort for it guarantees one can count
on it. 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. 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.
 

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,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top