How to flag onclick() and confirm() using DOM

D

donpro-2003

Hi,

I have an session application where the user logs out via a simplt
logot link. The code to do this is:
<a id="logout" title="Log out" href="logout.php" onClick="return
confirm('Do you really want to log out?')">Logout</a>

So if the user answers YES to the confim, logot.php is run and the
user is logged ot. If the user answers NO, they remain on the page.

I removed the onClick() and tried to use DOM but I find that with my
code, the user gets logged ot regardless of whether they choose YES or
NO so obviosly, my code is incomplete. I present it below, if anyon
can help, I wodl appreiciate it.

HTML
-------
<a id="logout" title="Log out" href="logout.php">Logout</a>

JavaScript
========
function addEvent(elm, evType, fn, useCapture) {
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent) {
var r = elm.attachEvent('on' + evType, fn);
return r;
} else {
elm['on' + evType] = fn;
}
}

function handleClick(e) {
return confirm('Do you really want to log out?');
}

function addListeners() {
if (!document.getElementById) {
return;
}

var logout_link = document.getElementById('logout');
addEvent(logout_link, 'click', handleClick, false);
}

addEvent(window, 'load', addListeners, false);
 
D

David Mark

Hi,

I have an session application where the user logs out via a simplt
logot link. The code to do this is:
<a id="logout" title="Log out" href="logout.php" onClick="return
confirm('Do you really want to log out?')">Logout</a>

So if the user answers YES to the confim, logot.php is run and the
user is logged ot. If the user answers NO, they remain on the page.

I removed the onClick() and tried to use DOM but I find that with my
code, the user gets logged ot regardless of whether they choose YES or
NO so obviosly, my code is incomplete. I present it below, if anyon
can help, I wodl appreiciate it.

HTML
-------
<a id="logout" title="Log out" href="logout.php">Logout</a>

JavaScript
========
function addEvent(elm, evType, fn, useCapture) {

The useCapture parameter is only used by one of three branches, which
makes the interface ambiguous.
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
} else if (elm.attachEvent) {

You don't need the else. The previous clauses returns.
var r = elm.attachEvent('on' + evType, fn);
return r;
} else {

Same here.
elm['on' + evType] = fn;

This is another ambiguity. If an event handler already exists, you
need to combine it with fn.
}

}

function handleClick(e) {
return confirm('Do you really want to log out?');

if (!confirm('Do you really want to log out?')) {
e = e || window.event;
if (e.preventDefault) { e.preventDefault(); }
e.returnValue = false;
}

Also, the message should be a statement, not a question (e.g. "This
action will log you out.")
}

function addListeners() {
if (!document.getElementById) {
return;
}

Lose this.
var logout_link = document.getElementById('logout');
addEvent(logout_link, 'click', handleClick, false);

}

addEvent(window, 'load', addListeners, false);

if (this.document.getElementById) { addEvent(this, 'load',
addListeners); }
 
R

Richard Cornford

David said:
On Oct 27, 5:11 pm, (e-mail address removed) wrote:

The useCapture parameter is only used by one of three
branches, which makes the interface ambiguous.

Absolutely. The fact that IE cannot capture at all suggests that this
type of attempted cross-browser function should not offer the option
externally. It should just set capturing to false in the
addEventListener branch. I cannot think of anything worse than having
capturing going on in some browsers while others were reacting to 'at
target' and bubbled events, that would be chaotic.
<snip>

Still, at least this version is testing for the method on the argument
rather than inferring its existence form window.addEventListener.

Richard.
 
D

David Mark

Absolutely. The fact that IE cannot capture at all suggests that this
type of attempted cross-browser function should not offer the option
externally. It should just set capturing to false in the
addEventListener branch. I cannot think of anything worse than having
capturing going on in some browsers while others were reacting to 'at
target' and bubbled events, that would be chaotic.


<snip>

Still, at least this version is testing for the method on the argument
rather than inferring its existence form window.addEventListener.

In this context, that makes sense. If you want to do a one-off
feature detect for addEventListener/attachEvent, would you test an
arbitrary DOM element (e.g. HTML?) It seems that code that attaches
events to window, document and DOM elements would need to be broken up
into three functions (unless you want to test arguments every time.)

In practice, I have never encountered an agent that supports these
methods for the window object, but does not support them for elements.

On a similar note, would testing for document.getElementsByTagName not
imply that the method is supported by elements? I suppose if it to be
used as an element method, then it would be more direct to test the
HTML element.

For instance, I recently decided that I wanted a backward-compatible
wrapper for getElementsByTagName. The reason is that many of my
widgets have to degrade for IE4 and other lesser agents because of
this one unsupported method. Originally, I had but one method, but
after considering this post, I broke it up into two:

var documentElementsByTagName, elementElementsByTagName;
var doc = this.document;

if (doc) {
(function() {
var html;

// Some older versions of IE choke on "*" with gEBTN
function commonElementsByTagName(el, t) {
return (t == '*' && el.all)?
el.all:el.getElementsByTagName(t);
}

documentElementsByTagName = (function() {
if (doc.getElementsByTagName) { return function(t) { return
commonElementsByTagName(doc, t); }; }
if (doc.all && doc.all.tags) { return function(t) { return
doc.all.tags(t); }; }
})();

html = doc.documentElement || (documentElementsByTagName &&
documentElementsByTagName('html')[0]);

if (html) {
elementElementsByTagName = (function() {
if (html.getElementsByTagName) { return
commonElementsByTagName; }
if (html.all && html.all.tags) { return function(el, t)
{ return el.all.tags(t); }; }
})();
}
})();
}

Do you think having two functions for this is overkill? If not, would
it also make sense to have three for attaching events?

As an aside, I have noticed that none of the current versions of the
"big three" agree on what getElementsByTagName (or all.tags) is
supposed to return for "*". IE is the only one that returns the
doctype and Opera adds text objects for inline script and style
blocks.

Now if I could just get IE4 to load without crashing on XP (oddly
enough, IE3 works fine.) Or maybe I should just be content with
unscripted content on those two (and other agents that don't support
getElementsByTagName) as, assuming I can even get IE4 working, I
imagine I will run into other issues with most widgets once the
getElementsByTagName hurdle is cleared.
 
R

Richard Cornford

David said:
In this context, that makes sense. If you want to do a
one-off feature detect for addEventListener/attachEvent,
would you test an arbitrary DOM element (e.g. HTML?)

Probably, though more likely BODY or one of its descendants. Because
the - addEventListener - is defined as being an optional part of the
Node interface it should be reasonable to assume that either all Nodes
have the method or that no Nodes have the method. In reality that won't
work. For a start text Nodes often do not have the method (as it is
generally impractical to use text nodes because IE has no equivalent at
that level of its DOM) so you might shift the interest to only object
implementing the Element interface for expedience. But some elements
(the decedents of the HEAD) will never receive events so a pragmatic DOM
may not provide the method on them.
It seems that code that attaches events to window, document
and DOM elements would need to be broken up into three
functions (unless you want to test arguments every time.)

The document is supposed to be an object implementing the Node interface
in addition to the Document interface, so if Elements have -
addEventListener - then the document should also have that method. But
expedience may still suggest separate handling.

The window absolutely needs separate handling because there is nothing
to suggest that it should have any event handling methods (beyond the
historic precedence of intrinsic event properties).
In practice, I have never encountered an agent that
supports these methods for the window object, but does
not support them for elements.

But there are browsers where the window does not have the methods but
the Elements do, so an inference from the window to the elements would
have sup-optimal results.
On a similar note, would testing for
document.getElementsByTagName not imply that the method
is supported by elements? I suppose if it to be used as
an element method, then it would be more direct to test
the HTML element.

In respect to the Documents and Elements, both should have the method,
but they are actually two methods defined on different interfaces so an
inference from one to the other would not be valid. Though I am not
aware of any environment where that inference would be problem is made.
For instance, I recently decided that I wanted a backward-compatible
wrapper for getElementsByTagName. The reason is that many of my
widgets have to degrade for IE4 and other lesser agents because of
this one unsupported method. Originally, I had but one method, but
after considering this post, I broke it up into two:
documentElementsByTagName = (function() {
if (doc.getElementsByTagName) { return function(t) { return
commonElementsByTagName(doc, t); }; }
if (doc.all && doc.all.tags) { return function(t) { return
doc.all.tags(t); }; }
})();

html = doc.documentElement || (documentElementsByTagName &&
documentElementsByTagName('html')[0]);


I wish you would do something about manually wrapping the code you post
within the wrapping margins of your newsreader. It would make it much
easier to read and javascript is so tolerate of white-space insertion
that it is not that difficult a task.
if (html) {
elementElementsByTagName = (function() {
if (html.getElementsByTagName) { return
commonElementsByTagName; }
if (html.all && html.all.tags) { return function(el, t)
{ return el.all.tags(t); }; }
})();
}
})();
}

Do you think having two functions for this is overkill?
No.

If not, would it also make sense to have three for
attaching events?

Avoiding invalid assumptions and inferences increases reliability in
cross-browser code. The cost of an extra couple of function objects and
a little extra code download is not so high when the result is greater
reliability.
As an aside, I have noticed that none of the current versions
of the "big three" agree on what getElementsByTagName
(or all.tags) is supposed to return for "*". IE is the
only one that returns the doctype and Opera adds text
objects for inline script and style blocks.

Neither of those reflect on the behaviour of -
document.getElementsByTagName('*') - because for IE and Opera you are
using - document.all - in both cases, and - docuent.all - has no public
specification.
Now if I could just get IE4 to load without crashing on XP
(oddly enough, IE3 works fine.) Or maybe I should just be
content with unscripted content on those two (and other
agents that don't support getElementsByTagName) as, assuming
I can even get IE4 working, I imagine I will run into other
issues with most widgets once the getElementsByTagName hurdle
is cleared.

You won't get - document.getElementsByTagName('*') - to work on IE 5
because the wildcard is DOM Level 2 and IE 5 isn't. So using that one
method alone means abandoning support for more IE versions that just IE
<- 4.

Richard.
 
D

David Mark

In this context, that makes sense. If you want to do a
one-off feature detect for addEventListener/attachEvent,
would you test an arbitrary DOM element (e.g. HTML?)

Probably, though more likely BODY or one of its descendants. Because
the - addEventListener - is defined as being an optional part of the
Node interface it should be reasonable to assume that either all Nodes
have the method or that no Nodes have the method. In reality that won't
work. For a start text Nodes often do not have the method (as it is
generally impractical to use text nodes because IE has no equivalent at
that level of its DOM) so you might shift the interest to only object
implementing the Element interface for expedience. But some elements
(the decedents of the HEAD) will never receive events so a pragmatic DOM
may not provide the method on them.
It seems that code that attaches events to window, document
and DOM elements would need to be broken up into three
functions (unless you want to test arguments every time.)

The document is supposed to be an object implementing the Node interface
in addition to the Document interface, so if Elements have -
addEventListener - then the document should also have that method. But
expedience may still suggest separate handling.

The window absolutely needs separate handling because there is nothing
to suggest that it should have any event handling methods (beyond the
historic precedence of intrinsic event properties).
In practice, I have never encountered an agent that
supports these methods for the window object, but does
not support them for elements.

But there are browsers where the window does not have the methods but
the Elements do, so an inference from the window to the elements would
have sup-optimal results.
On a similar note, would testing for
document.getElementsByTagName not imply that the method
is supported by elements? I suppose if it to be used as
an element method, then it would be more direct to test
the HTML element.

In respect to the Documents and Elements, both should have the method,
but they are actually two methods defined on different interfaces so an
inference from one to the other would not be valid. Though I am not
aware of any environment where that inference would be problem is made.






For instance, I recently decided that I wanted a backward-compatible
wrapper for getElementsByTagName. The reason is that many of my
widgets have to degrade for IE4 and other lesser agents because of
this one unsupported method. Originally, I had but one method, but
after considering this post, I broke it up into two:
documentElementsByTagName = (function() {
if (doc.getElementsByTagName) { return function(t) { return
commonElementsByTagName(doc, t); }; }
if (doc.all && doc.all.tags) { return function(t) { return
doc.all.tags(t); }; }
})();
html = doc.documentElement || (documentElementsByTagName &&
documentElementsByTagName('html')[0]);

I wish you would do something about manually wrapping the code you post
within the wrapping margins of your newsreader. It would make it much
easier to read and javascript is so tolerate of white-space insertion
that it is not that difficult a task.

Sorry about that.
Avoiding invalid assumptions and inferences increases reliability in
cross-browser code. The cost of an extra couple of function objects and
a little extra code download is not so high when the result is greater
reliability.


Neither of those reflect on the behaviour of -
document.getElementsByTagName('*') - because for IE and Opera you are
using - document.all - in both cases, and - docuent.all - has no public
specification.

No, I tested Opera and IE with direct calls to
document.getElementsByTagName.
You won't get - document.getElementsByTagName('*') - to work on IE 5
because the wildcard is DOM Level 2 and IE 5 isn't. So using that one

That's why I used document.all here:

function commonElementsByTagName(el, t) {
return (t == '*' && el.all)?el.all:el.getElementsByTagName(t);
}

That should cover IE3-5.
 

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

Latest Threads

Top