Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Feature testing DOM0 event interface

Reply
Thread Tools

Feature testing DOM0 event interface

 
 
Peter Michaux
Guest
Posts: n/a
 
      02-12-2008
It seems people make a regular habit of testing for the
addEventListener and attachEvent methods but they just assume the DOM0-
type event interface exists like element.onclick.

At least recent versions of Opera, Safari, IE allow for a feature test
by all returning true for the following

javascript:alert(typeof document.documentElement.onclick !=
'undefined')

Unfortunately, Firefox returns false for the above.

Does anyone have a universal feature test for this?

Thanks,
Peter
 
Reply With Quote
 
 
 
 
David Mark
Guest
Posts: n/a
 
      02-12-2008
On Feb 12, 12:46*pm, Peter Michaux <(E-Mail Removed)> wrote:
> It seems people make a regular habit of testing for the
> addEventListener and attachEvent methods but they just assume the DOM0-
> type event interface exists like element.onclick.


This assumption won't hurt anything if the page is designed to degrade
gracefully.

>
> At least recent versions of Opera, Safari, IE allow for a feature test
> by all returning true for the following
>
> javascript:alert(typeof document.documentElement.onclick !=
> 'undefined')
>
> Unfortunately, Firefox returns false for the above.
>
> Does anyone have a universal feature test for this?
>


This isn't ideal as it relies on setAttribute, but it does work for
Firefox. Alternatively, you could define the onclick attribute in the
markup.

var el = getAnElement(), dom0 = true;
if (typeof el.onclick == 'undefined' &&
isHostMethod(el, 'setAttribute')) {
el.setAttribute('onclick', '(function() {})');
dom0 = (typeof el.onclick == 'function');
el.setAttribute('onclick', '');
}

If a design relies on DOM0 event support, the best solution is to call
its gateway function like this:

this.onload = myGateway;

Is this in regard to the Safari 1.x preventDefault bug on click/
dblclick? I have thought about that one and I don't think it requires
a workaround. If, for instance, a user of Safari 1.x clicks a link
that has a click event listener and preventDefault fails, the browser
will fire the event and then navigate normally. As long as the page
is designed to work without script, this should not cause an issue. I
know some libraries (e.g. YUI) sniff for the older Safari versions and
fallback to DOM0 for click/dblclick, but I think that is a mistake.
 
Reply With Quote
 
 
 
 
Peter Michaux
Guest
Posts: n/a
 
      02-12-2008
On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:
> On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:
>
> > It seems people make a regular habit of testing for the
> > addEventListener and attachEvent methods but they just assume the DOM0-
> > type event interface exists like element.onclick.

>
> This assumption won't hurt anything if the page is designed to degrade
> gracefully.


I have a situation where it will hurt and this is a common situation.
A page arrives with its HTML for static viewing. I want to manipulate
the DOM structure and page CSS to create a widget. I think of the
point at which the DOM and CSS are manipulated as "the point of no
return". Before I make these manipulations I need to make sure the
widget will function completely. If the DOM structure and CSS both
work, but the browser doesn't have correct event handling, then the
widget will be useless and some content will not be visible to the
user.


> > At least recent versions of Opera, Safari, IE allow for a feature test
> > by all returning true for the following

>
> > javascript:alert(typeof document.documentElement.onclick !=
> > 'undefined')

>
> > Unfortunately, Firefox returns false for the above.

>
> > Does anyone have a universal feature test for this?

>
> This isn't ideal as it relies on setAttribute, but it does work for
> Firefox. Alternatively, you could define the onclick attribute in the
> markup.
>
> var el = getAnElement(), dom0 = true;
> if (typeof el.onclick == 'undefined' &&
> isHostMethod(el, 'setAttribute')) {
> el.setAttribute('onclick', '(function() {})');
> dom0 = (typeof el.onclick == 'function');
> el.setAttribute('onclick', '');
>
> }


There doesn't seem to be anything in the Element.setAttribute spec
that make me think this is a particularly robust test.

http://www.w3.org/TR/2000/REC-DOM-Le...tml#ID-F68F082


> If a design relies on DOM0 event support, the best solution is to call
> its gateway function like this:
>
> this.onload = myGateway;


I agreed that this is a solid solution. What I'm actually trying to
determine if the above will work. Here is why...

When a page is built with progressive enhancement in mind, the page
looks like like the unenhanced version while the whole page loads.
When window.onload occurs, then the page can be enhanced and made to
look like the enhanced version. For the user with a browser that will
support the enhanced version, this is unsightly. For example, a huge
list of nested ul elements appear on the page for a while while the
page loads, when window.onload fires, the hander determines that the
nested ul elements can be converted into a drop-down menu or tree
menu. When this conversion happens the page appears to "jump" as the
CSS changes and the page is re-rendered. This is not really acceptable
as more users will be able to have the enhanced version than the
unenhanced version.

So what I want to do is the following...

When the page is loading, determine if the browser has enough features
to "get out of trouble". If that is the case then add a CSS file to
the page with document.write, that will give the page an acceptable
appearance while the page loads. When window.onload fires, determine
if the widget can fully function and enable that widget. If the widget
cannot fully function then execute the "get out of trouble" and revert
the styling of the HTML to something more pleasing for the unenlivened
version. It almost allows me to *tentatively* cross the point of no
return with just one foot so the page looks nicer during load.

Makes sense?

> Is this in regard to the Safari 1.x preventDefault bug on click/
> dblclick?


Yes my question also impacts this.

> I have thought about that one and I don't think it requires
> a workaround.


You may be right that the workaround is not necessary. I need to think
about this more.


> If, for instance, a user of Safari 1.x clicks a link
> that has a click event listener and preventDefault fails, the browser
> will fire the event and then navigate normally. As long as the page
> is designed to work without script, this should not cause an issue.


But it might cause an issue if the JavaScript does something that
shouldn't be followed by the normal navigation. I know we aren't
supposed to use <a> links to add items to a shopping cart but suppose
someone did. And then suppose they used hijax[1] to make the link add
the item to the cart with Ajax. If the Ajax is initiated an then the
link is followed, the item will be added to the cart twice.

[1] http://domscripting.com/blog/display/41

I am completely aware this is a crappy example but my gut tells me
there must be situations where having the JavaScript run followed by
the normal navigation is bad.

I suppose the JavaScript could be run after a timeout and that way it
only runs if the normal navigation didn't work. Messy solution.


> I know some libraries (e.g. YUI) sniff for the older Safari versions and
> fallback to DOM0 for click/dblclick, but I think that is a mistake.


I think the sniff is also a mistake. I use DOM0 listeners for all
click events. That way I treat all browsers equally and don't need the
sniff. I think it would be fine to use DOM0 listeners for all event
handlers. There really isn't a need for addEventListener and
attachEvent because a wrapper API around DOM0 can do it all anyway. My
problem is that right now I am not testing that DOM0 will work. This
is not a large practical problem for me but it is a large problem in
trying to write a widget properly.

By the way, this problem is the last detail for an article I am
writing for my blog about writing progressive enhancement widgets (a
tabbed pane) for the general web. It uses the isHostMethod etc. If
anyone is interested in reviewing the article I can post it here for
debate. I've never seen such an article and I think such an article
has long been needed.

Peter
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      02-12-2008
On Feb 12, 4:15*pm, Peter Michaux <(E-Mail Removed)> wrote:
> On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:
>
> > On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > It seems people make a regular habit of testing for the
> > > addEventListener and attachEvent methods but they just assume the DOM0-
> > > type event interface exists like element.onclick.

>
> > This assumption won't hurt anything if the page is designed to degrade
> > gracefully.

>
> I have a situation where it will hurt and this is a common situation.
> A page arrives with its HTML for static viewing. I want to manipulate
> the DOM structure and page CSS to create a widget. I think of the
> point at which the DOM and CSS are manipulated as "the point of no
> return". Before I make these manipulations I need to make sure the
> widget will function completely. If the DOM structure and CSS both
> work, but the browser doesn't have correct event handling, then the
> widget will be useless and some content will not be visible to the
> user.
>
>
>
>
>
> > > At least recent versions of Opera, Safari, IE allow for a feature test
> > > by all returning true for the following

>
> > > javascript:alert(typeof document.documentElement.onclick !=
> > > 'undefined')

>
> > > Unfortunately, Firefox returns false for the above.

>
> > > Does anyone have a universal feature test for this?

>
> > This isn't ideal as it relies on setAttribute, but it does work for
> > Firefox. *Alternatively, you could define the onclick attribute in the
> > markup.

>
> > var el = getAnElement(), dom0 = true;
> > if (typeof el.onclick == 'undefined' &&
> > * * isHostMethod(el, 'setAttribute')) {
> > * el.setAttribute('onclick', '(function() {})');
> > * dom0 = (typeof el.onclick == 'function');
> > * el.setAttribute('onclick', '');

>
> > }

>
> There doesn't seem to be anything in the Element.setAttribute spec
> that make me think this is a particularly robust test.
>


How so? It seems quite reasonable to me. Of course, if IE8 fails to
fix setAttribute and returns undefined for an unset onclick property,
you will need to use a suitable setAttribute wrapper.

> http://www.w3.org/TR/2000/REC-DOM-Le.../core.html#ID-...
>
> > If a design relies on DOM0 event support, the best solution is to call
> > its gateway function like this:

>
> > this.onload = myGateway;

>
> I agreed that this is a solid solution. What I'm actually trying to
> determine if the above will work. Here is why...
>
> When a page is built with progressive enhancement in mind, the page
> looks like like the unenhanced version while the whole page loads.
> When window.onload occurs, then the page can be enhanced and made to
> look like the enhanced version. For the user with a browser that will
> support the enhanced version, this is unsightly. For example, a huge


Right.

> list of nested ul elements appear on the page for a while while the
> page loads, when window.onload fires, the hander determines that the
> nested ul elements can be converted into a drop-down menu or tree
> menu. When this conversion happens the page appears to "jump" as the
> CSS changes and the page is re-rendered. This is not really acceptable
> as more users will be able to have the enhanced version than the
> unenhanced version.


I see. You want to test before you add a style rule to hide the
nested lists. Makes sense. Of course, what scripted browser supports
adding style rules, but not DOM0 events?

>
> So what I want to do is the following...
>
> When the page is loading, determine if the browser has enough features
> to "get out of trouble". If that is the case then add a CSS file to
> the page with document.write, that will give the page an acceptable
> appearance while the page loads. When window.onload fires, determine


Right.

> if the widget can fully function and enable that widget. If the widget
> cannot fully function then execute the "get out of trouble" and revert
> the styling of the HTML to something more pleasing for the unenlivened


Or, in some cases, something that won't completely break the page for
the odd browser that supports dynamic styles, but not DOM0 events
(e.g. un-hide the nested lists.)

> version. It almost allows me to *tentatively* cross the point of no
> return with just one foot so the page looks nicer during load.
>
> Makes sense?


Yes.

>
> > Is this in regard to the Safari 1.x preventDefault bug on click/
> > dblclick?

>
> Yes my question also impacts this.
>
> > I have thought about that one and I don't think it requires
> > a workaround.

>
> You may be right that the workaround is not necessary. I need to think
> about this more.
>
> > If, for instance, a user of Safari 1.x clicks a link
> > that has a click event listener and preventDefault fails, the browser
> > will fire the event and then navigate normally. As long as the page
> > is designed to work without script, this should not cause an issue.

>
> But it might cause an issue if the JavaScript does something that
> shouldn't be followed by the normal navigation. I know we aren't
> supposed to use <a> links to add items to a shopping cart but suppose
> someone did. And then suppose they used hijax[1] to make the link add
> the item to the cart with Ajax. If the Ajax is initiated an then the
> link is followed, the item will be added to the cart twice.


Yes. But does that old Safari version even support Ajax? If so, you
already hinted at the solution: use a button.

>
> [1]http://domscripting.com/blog/display/41
>
> I am completely aware this is a crappy example but my gut tells me
> there must be situations where having the JavaScript run followed by
> the normal navigation is bad.


It's possible. I wonder how many people still use Safari 1.x though.

>
> I suppose the JavaScript could be run after a timeout and that way it
> only runs if the normal navigation didn't work. Messy solution.


Yes, that would be ugly.

>
> > I know some libraries (e.g. YUI) sniff for the older Safari versions and
> > fallback to DOM0 for click/dblclick, but I think that is a mistake.

>
> I think the sniff is also a mistake. I use DOM0 listeners for all
> click events. That way I treat all browsers equally and don't need the
> sniff. I think it would be fine to use DOM0 listeners for all event


I'm not big on using DOM0 listeners to simulate addEventListener/
attachEvent (unless neither exists.) For one, it slows down event
handling significantly. And then there are the possibilities of
collisions with DOM0 listeners defined in the markup or attached by
other scripts.

> handlers. There really isn't a need for addEventListener and
> attachEvent because a wrapper API around DOM0 can do it all anyway. My


It can do it all, but is considerably slower in doing it. Responding
to user input is the last place I would want a bottleneck.

> problem is that right now I am not testing that DOM0 will work. This
> is not a large practical problem for me but it is a large problem in
> trying to write a widget properly.


Large in what way? I can't think of a user agent that would add a
style rule with script, but not handle DOM0 events.

>
> By the way, this problem is the last detail for an article I am
> writing for my blog about writing progressive enhancement widgets (a
> tabbed pane) for the general web. It uses the isHostMethod etc.


Sounds like a useful article. Every time I set out to write a tabbed
anything, I run into a problem when style is disabled, but scripting
is enabled. The only solution I have found for this is to make the
links in the tabs point to bookmarks in the page and to allow the
default click action to navigate to them. This obviously has an
unwanted side effect when style and scripting are both enabled (the
tabs scroll off the page after switching panes.) How did you handle
this odd case?

If
> anyone is interested in reviewing the article I can post it here for
> debate. I've never seen such an article and I think such an article
> has long been needed.


Post it. We've dealt with the issue of turning a list and a series of
div's into tabbed panes before, but never the issue of missing DOM0
event support (AFAIK.)
 
Reply With Quote
 
Peter Michaux
Guest
Posts: n/a
 
      02-12-2008
On Feb 12, 2:43 pm, David Mark <(E-Mail Removed)> wrote:
> On Feb 12, 4:15 pm, Peter Michaux <(E-Mail Removed)> wrote:
>
> > On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:

>
> > > On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > > It seems people make a regular habit of testing for the
> > > > addEventListener and attachEvent methods but they just assume the DOM0-
> > > > type event interface exists like element.onclick.


[snip]

> > > > Does anyone have a universal feature test for this?

>
> > > This isn't ideal as it relies on setAttribute, but it does work for
> > > Firefox. Alternatively, you could define the onclick attribute in the
> > > markup.

>
> > > var el = getAnElement(), dom0 = true;
> > > if (typeof el.onclick == 'undefined' &&
> > > isHostMethod(el, 'setAttribute')) {
> > > el.setAttribute('onclick', '(function() {})');
> > > dom0 = (typeof el.onclick == 'function');
> > > el.setAttribute('onclick', '');

>
> > > }

>
> > There doesn't seem to be anything in the Element.setAttribute spec
> > that make me think this is a particularly robust test.

>
> How so? It seems quite reasonable to me. Of course, if IE8 fails to
> fix setAttribute and returns undefined for an unset onclick property,
> you will need to use a suitable setAttribute wrapper.
>
> >http://www.w3.org/TR/2000/REC-DOM-Le.../core.html#ID-...


The spec says that if the attribute doesn't exist, it will create it.
It doesn't say that the fact that an on* attribute can be created
means it will be used an an event handler.

[snip]

> I see. You want to test before you add a style rule to hide the
> nested lists. Makes sense. Of course, what scripted browser supports
> adding style rules, but not DOM0 events?


I've never encountered one but that would be feature inference based
on two very unrelated features: style and events.

[snip]

> > But it might cause an issue if the JavaScript does something that
> > shouldn't be followed by the normal navigation. I know we aren't
> > supposed to use <a> links to add items to a shopping cart but suppose
> > someone did. And then suppose they used hijax[1] to make the link add
> > the item to the cart with Ajax. If the Ajax is initiated an then the
> > link is followed, the item will be added to the cart twice.

>
> Yes. But does that old Safari version even support Ajax? If so, you
> already hinted at the solution: use a button.


I know someone with Safari 1.9 because she has OS X 10.3 and so can't
upgrade.

Early point releases of Safari 2 also had this problem so the problem
was still occurring in a browser versions released only about a year
or so ago.


[snip about using DOM0 event instead of newer]

> It can do it all, but is considerably slower in doing it. Responding
> to user input is the last place I would want a bottleneck.


It can't be that much slower. It is only a matter of running one loop
in the JavaScript rather than in the C/C++/Java of the browser. Each
individual handler will probably do something that will eclipse the
time taken to run this loop.

[snip]

> > problem is that right now I am not testing that DOM0 will work. This
> > is not a large practical problem for me but it is a large problem in
> > trying to write a widget properly.

>
> Large in what way?


I didn't even need the word "large". It isn't a practical problem for
me at all. Because...

> I can't think of a user agent that would add a
> style rule with script, but not handle DOM0 events.


True but it is unrelated feature inference.

> > By the way, this problem is the last detail for an article I am
> > writing for my blog about writing progressive enhancement widgets (a
> > tabbed pane) for the general web. It uses the isHostMethod etc.

>
> Sounds like a useful article. Every time I set out to write a tabbed
> anything, I run into a problem when style is disabled, but scripting
> is enabled. The only solution I have found for this is to make the
> links in the tabs point to bookmarks in the page and to allow the
> default click action to navigate to them. This obviously has an
> unwanted side effect when style and scripting are both enabled (the
> tabs scroll off the page after switching panes.) How did you handle
> this odd case?


I didn't need to. I'll post it and you will see why.

> If
>
> > anyone is interested in reviewing the article I can post it here for
> > debate. I've never seen such an article and I think such an article
> > has long been needed.

>
> Post it. We've dealt with the issue of turning a list and a series of
> div's into tabbed panes before, but never the issue of missing DOM0
> event support (AFAIK.)


I haven't finished writing the article but I can post the code for the
example later today.

Thanks,
Peter
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      02-12-2008
On Feb 12, 6:16*pm, Peter Michaux <(E-Mail Removed)> wrote:
> On Feb 12, 2:43 pm, David Mark <(E-Mail Removed)> wrote:
>
> > On Feb 12, 4:15 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:

>
> > > > On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > > > It seems people make a regular habit of testing for the
> > > > > addEventListener and attachEvent methods but they just assume the DOM0-
> > > > > type event interface exists like element.onclick.

>
> [snip]
>
>
>
>
>
> > > > > Does anyone have a universal feature test for this?

>
> > > > This isn't ideal as it relies on setAttribute, but it does work for
> > > > Firefox. *Alternatively, you could define the onclick attribute inthe
> > > > markup.

>
> > > > var el = getAnElement(), dom0 = true;
> > > > if (typeof el.onclick == 'undefined' &&
> > > > * * isHostMethod(el, 'setAttribute')) {
> > > > * el.setAttribute('onclick', '(function() {})');
> > > > * dom0 = (typeof el.onclick == 'function');
> > > > * el.setAttribute('onclick', '');

>
> > > > }

>
> > > There doesn't seem to be anything in the Element.setAttribute spec
> > > that make me think this is a particularly robust test.

>
> > How so? *It seems quite reasonable to me. *Of course, if IE8 fails to
> > fix setAttribute and returns undefined for an unset onclick property,
> > you will need to use a suitable setAttribute wrapper.

>
> > >http://www.w3.org/TR/2000/REC-DOM-Le.../core.html#ID-....

>
> The spec says that if the attribute doesn't exist, it will create it.
> It doesn't say that the fact that an on* attribute can be created
> means it will be used an an event handler.


The test checks if the property is a function. An implementation that
does not support DOM0 isn't likely to pass.

>
> [snip]
>
> > I see. *You want to test before you add a style rule to hide the
> > nested lists. *Makes sense. *Of course, what scripted browser supports
> > adding style rules, but not DOM0 events?

>
> I've never encountered one but that would be feature inference based
> on two very unrelated features: style and events.


No question.

>
> [snip]
>
> > > But it might cause an issue if the JavaScript does something that
> > > shouldn't be followed by the normal navigation. I know we aren't
> > > supposed to use <a> links to add items to a shopping cart but suppose
> > > someone did. And then suppose they used hijax[1] to make the link add
> > > the item to the cart with Ajax. If the Ajax is initiated an then the
> > > link is followed, the item will be added to the cart twice.

>
> > Yes. *But does that old Safari version even support Ajax? *If so, you
> > already hinted at the solution: use a button.

>
> I know someone with Safari 1.9 because she has OS X 10.3 and so can't
> upgrade.
>
> Early point releases of Safari 2 also had this problem so the problem
> was still occurring in a browser versions released only about a year
> or so ago.


Do those auto-upgrade?

>
> [snip about using DOM0 event instead of newer]
>
> > It can do it all, but is considerably slower in doing it. *Responding
> > to user input is the last place I would want a bottleneck.

>
> It can't be that much slower. It is only a matter of running one loop
> in the JavaScript rather than in the C/C++/Java of the browser. Each
> individual handler will probably do something that will eclipse the
> time taken to run this loop.


You've got to find the events for the element in question and then
loop through them. The overhead may not be significant when compared
to the code in the listeners, but then those should also be as light
as possible. It could cause a palpable slowdown in events like
mousemove, resize, scroll, etc.

>
> [snip]
>
> > > problem is that right now I am not testing that DOM0 will work. This
> > > is not a large practical problem for me but it is a large problem in
> > > trying to write a widget properly.

>
> > Large in what way?

>
> I didn't even need the word "large". It isn't a practical problem for
> me at all. Because...
>
> > I can't think of a user agent that would add a
> > style rule with script, but not handle DOM0 events.

>
> True but it is unrelated feature inference.
>
> > > By the way, this problem is the last detail for an article I am
> > > writing for my blog about writing progressive enhancement widgets (a
> > > tabbed pane) for the general web. It uses the isHostMethod etc.

>
> > Sounds like a useful article. *Every time I set out to write a tabbed
> > anything, I run into a problem when style is disabled, but scripting
> > is enabled. *The only solution I have found for this is to make the
> > links in the tabs point to bookmarks in the page and to allow the
> > default click action to navigate to them. *This obviously has an
> > unwanted side effect when style and scripting are both enabled (the
> > tabs scroll off the page after switching panes.) *How did you handle
> > this odd case?

>
> I didn't need to. I'll post it and you will see why.


I'm interested to see what you came up with.

 
Reply With Quote
 
Peter Michaux
Guest
Posts: n/a
 
      02-13-2008
On Feb 12, 3:32 pm, David Mark <(E-Mail Removed)> wrote:
> On Feb 12, 6:16 pm, Peter Michaux <(E-Mail Removed)> wrote:
>
>
>
> > On Feb 12, 2:43 pm, David Mark <(E-Mail Removed)> wrote:

>
> > > On Feb 12, 4:15 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > > On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:

>
> > > > > On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > > > > It seems people make a regular habit of testing for the
> > > > > > addEventListener and attachEvent methods but they just assume the DOM0-
> > > > > > type event interface exists like element.onclick.

>
> > [snip]

>
> > > > > > Does anyone have a universal feature test for this?

>
> > > > > This isn't ideal as it relies on setAttribute, but it does work for
> > > > > Firefox. Alternatively, you could define the onclick attribute in the
> > > > > markup.

>
> > > > > var el = getAnElement(), dom0 = true;
> > > > > if (typeof el.onclick == 'undefined' &&
> > > > > isHostMethod(el, 'setAttribute')) {
> > > > > el.setAttribute('onclick', '(function() {})');
> > > > > dom0 = (typeof el.onclick == 'function');
> > > > > el.setAttribute('onclick', '');

>
> > > > > }

>
> > > > There doesn't seem to be anything in the Element.setAttribute spec
> > > > that make me think this is a particularly robust test.

>
> > > How so? It seems quite reasonable to me. Of course, if IE8 fails to
> > > fix setAttribute and returns undefined for an unset onclick property,
> > > you will need to use a suitable setAttribute wrapper.

>
> > > >http://www.w3.org/TR/2000/REC-DOM-Le.../core.html#ID-...

>
> > The spec says that if the attribute doesn't exist, it will create it.
> > It doesn't say that the fact that an on* attribute can be created
> > means it will be used an an event handler.

>
> The test checks if the property is a function. An implementation that
> does not support DOM0 isn't likely to pass.


It is an interesting test and thanks for sharing it. I hoped there was
something a little more straight forward.

[snip]

> > > > But it might cause an issue if the JavaScript does something that
> > > > shouldn't be followed by the normal navigation. I know we aren't
> > > > supposed to use <a> links to add items to a shopping cart but suppose
> > > > someone did. And then suppose they used hijax[1] to make the link add
> > > > the item to the cart with Ajax. If the Ajax is initiated an then the
> > > > link is followed, the item will be added to the cart twice.

>
> > > Yes. But does that old Safari version even support Ajax? If so, you
> > > already hinted at the solution: use a button.

>
> > I know someone with Safari 1.9 because she has OS X 10.3 and so can't
> > upgrade.

>
> > Early point releases of Safari 2 also had this problem so the problem
> > was still occurring in a browser versions released only about a year
> > or so ago.

>
> Do those auto-upgrade?


Version 1.9 does not auto-upgrade because version 2 that requires OS X
10.4.

Version 2 does auto-upgrade all the way into version 3.


> > [snip about using DOM0 event instead of newer]

>
> > > It can do it all, but is considerably slower in doing it. Responding
> > > to user input is the last place I would want a bottleneck.

>
> > It can't be that much slower. It is only a matter of running one loop
> > in the JavaScript rather than in the C/C++/Java of the browser. Each
> > individual handler will probably do something that will eclipse the
> > time taken to run this loop.

>
> You've got to find the events for the element in question and then
> loop through them.


There is no need to find them. Here is some pseudo code...

function addListener(element, type, callback) {
if (!(element['on'+type])) {
element['on'+type] = function(e) {
var callbacks = arguments.callee.callbacks;
for (var i=0; i<callbacks.length; i++) {
callbacks[i](e);
}
};
element['on'+type].callbacks = [];
}
element['on'+type].push(callback);
};

[snip]

Peter
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      02-13-2008
On Feb 12, 7:16*pm, Peter Michaux <(E-Mail Removed)> wrote:
> On Feb 12, 3:32 pm, David Mark <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On Feb 12, 6:16 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > On Feb 12, 2:43 pm, David Mark <(E-Mail Removed)> wrote:

>
> > > > On Feb 12, 4:15 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > > > On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:

>
> > > > > > On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:

>
> > > > > > > It seems people make a regular habit of testing for the
> > > > > > > addEventListener and attachEvent methods but they just assume the DOM0-
> > > > > > > type event interface exists like element.onclick.

>
> > > [snip]

>
> > > > > > > Does anyone have a universal feature test for this?

>
> > > > > > This isn't ideal as it relies on setAttribute, but it does work for
> > > > > > Firefox. *Alternatively, you could define the onclick attribute in the
> > > > > > markup.

>
> > > > > > var el = getAnElement(), dom0 = true;
> > > > > > if (typeof el.onclick == 'undefined' &&
> > > > > > * * isHostMethod(el, 'setAttribute')) {
> > > > > > * el.setAttribute('onclick', '(function() {})');
> > > > > > * dom0 = (typeof el.onclick == 'function');
> > > > > > * el.setAttribute('onclick', '');

>
> > > > > > }

>
> > > > > There doesn't seem to be anything in the Element.setAttribute spec
> > > > > that make me think this is a particularly robust test.

>
> > > > How so? *It seems quite reasonable to me. *Of course, if IE8 fails to
> > > > fix setAttribute and returns undefined for an unset onclick property,
> > > > you will need to use a suitable setAttribute wrapper.

>
> > > > >http://www.w3.org/TR/2000/REC-DOM-Le.../core.html#ID-...

>
> > > The spec says that if the attribute doesn't exist, it will create it.
> > > It doesn't say that the fact that an on* attribute can be created
> > > means it will be used an an event handler.

>
> > The test checks if the property is a function. *An implementation that
> > does not support DOM0 isn't likely to pass.

>
> It is an interesting test and thanks for sharing it. I hoped there was
> something a little more straight forward.
>
> [snip]
>
>
>
>
>
> > > > > But it might cause an issue if the JavaScript does something that
> > > > > shouldn't be followed by the normal navigation. I know we aren't
> > > > > supposed to use <a> links to add items to a shopping cart but suppose
> > > > > someone did. And then suppose they used hijax[1] to make the link add
> > > > > the item to the cart with Ajax. If the Ajax is initiated an then the
> > > > > link is followed, the item will be added to the cart twice.

>
> > > > Yes. *But does that old Safari version even support Ajax? *If so, you
> > > > already hinted at the solution: use a button.

>
> > > I know someone with Safari 1.9 because she has OS X 10.3 and so can't
> > > upgrade.

>
> > > Early point releases of Safari 2 also had this problem so the problem
> > > was still occurring in a browser versions released only about a year
> > > or so ago.

>
> > Do those auto-upgrade?

>
> Version 1.9 does not auto-upgrade because version 2 that requires OS X
> 10.4.
>
> Version 2 does auto-upgrade all the way into version 3.


Then it is pretty much a Safari 1.x issue. Until OS X 10.3 dies out,
the issue will have to be considered on a case by case basis (I don't
see a general solution that is practical, unless you want to use DOM0
exclusively.)

>
> > > [snip about using DOM0 event instead of newer]

>
> > > > It can do it all, but is considerably slower in doing it. *Responding
> > > > to user input is the last place I would want a bottleneck.

>
> > > It can't be that much slower. It is only a matter of running one loop
> > > in the JavaScript rather than in the C/C++/Java of the browser. Each
> > > individual handler will probably do something that will eclipse the
> > > time taken to run this loop.

>
> > You've got to find the events for the element in question and then
> > loop through them.

>
> There is no need to find them. Here is some pseudo code...
>
> function addListener(element, type, callback) {
> * if (!(element['on'+type])) {
> * * * element['on'+type] = function(e) {
> * * * * var callbacks = arguments.callee.callbacks;
> * * * * for (var i=0; i<callbacks.length; i++) {
> * * * * * * callbacks[i](e);
> * * * * }
> * * * };
> * * * element['on'+type].callbacks = [];
> * }
> * element['on'+type].push(callback);
>
> };


That's not too bad, but clearly more is needed to emulate
addEventListener (e.g. preserve the "this" reference, handle callbacks
that return false, etc.) I recently added similar code to my
library. Rather than looping, I "chained" the (normalized) listeners
together. The biggest issue that came up was how to allow for
alternate contexts (i.e. setting "this" to something other than the
element.) I finally came up with a normalization/storage scheme that
works for attachEvent and DOM0 without leaking memory in IE. Thinking
about it now, starting off with something like the above may have led
to a simpler solution, though I think what I came up with will be
faster.

We should revisit this when the CWR addEventListener wrapper comes up
for discussion.
 
Reply With Quote
 
Peter Michaux
Guest
Posts: n/a
 
      02-16-2008
On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:
> On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:


> This isn't ideal as it relies on setAttribute, but it does work for
> Firefox. Alternatively, you could define the onclick attribute in the
> markup.
>
> var el = getAnElement(), dom0 = true;
> if (typeof el.onclick == 'undefined' &&
> isHostMethod(el, 'setAttribute')) {
> el.setAttribute('onclick', '(function() {})');
> dom0 = (typeof el.onclick == 'function');
> el.setAttribute('onclick', '');
>
> }



The setAttribute spec specifically states that the second argument is
not parsed and is treated like a string literal

<URL: http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-F68F082>

I don't like to use a test that will break if a browser becomes _more_
standards compliant. If Firefox starts to follow the standard the
above test will stop working.

---------

Here is a test that checks inline handlers are supported. Not related
to my initial question exactly. If they are not then I imagine that,
at best, the onclick attribute of the firstChild would be a string.

var el = document.createElement('div');
el.innerHTML = '<span onclick="alert(\'hi\');">hi</span>';
typeof el.firstChild.onclick;


It works in IE5+ and recent FF, S and O.

Peter
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      02-16-2008
On Feb 16, 1:26*pm, Peter Michaux <(E-Mail Removed)> wrote:
> On Feb 12, 12:23 pm, David Mark <(E-Mail Removed)> wrote:
>
> > On Feb 12, 12:46 pm, Peter Michaux <(E-Mail Removed)> wrote:
> > This isn't ideal as it relies on setAttribute, but it does work for
> > Firefox. *Alternatively, you could define the onclick attribute in the
> > markup.

>
> > var el = getAnElement(), dom0 = true;
> > if (typeof el.onclick == 'undefined' &&
> > * * isHostMethod(el, 'setAttribute')) {
> > * el.setAttribute('onclick', '(function() {})');
> > * dom0 = (typeof el.onclick == 'function');
> > * el.setAttribute('onclick', '');

>
> > }

>
> The setAttribute spec specifically states that the second argument is
> not parsed and is treated like a string literal


Absolutely.

>
> <URL:http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-....>
>
> I don't like to use a test that will break if a browser becomes _more_
> standards compliant. If Firefox starts to follow the standard the
> above test will stop working.


I don't follow you there. If you add an onclick attribute, the DOM
should return a function when the onclick property is evaluated
(assuming it supports the DOM0 event model.)

>
> ---------
>
> Here is a test that checks inline handlers are supported. Not related
> to my initial question exactly. If they are not then I imagine that,
> at best, the onclick attribute of the firstChild would be a string.
>
> var el = document.createElement('div');
> el.innerHTML = '<span onclick="alert(\'hi\');">hi</span>';
> typeof el.firstChild.onclick;


That's roughly the same thing, but it uses the non-standard innerHTML
property.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Mousewheel event does not support DOM0 in FF David Mark Javascript 9 06-04-2010 01:24 AM
typeof for feature testing host methods Peter Michaux Javascript 61 12-21-2007 09:36 PM
testing testing neville Computer Support 2 05-27-2005 09:57 AM
testing testing 123 daniel edwards Computer Support 4 05-20-2004 10:36 PM
testing--news2004--testing Boomer Computer Support 3 09-24-2003 06:54 PM



Advertisments