James Moe wrote:
1. The document.all property (array?) seems to be a popular IE-only
attribute. Other browsers (Opera, Mozilla) do not seem to care for it
Opera 7, and many other browsers do implement a document.all collection.
But most also support a W3C DOM standard alternative (as do recent IE
versions) so their use should be preferred and document.all relegated to
the status of potential fall-back for 2 or 3 dinosaur browsers.
which, of course, occasionally produces weird displays and
non-functional links. Is it, indeed, a IE-ism?
It certainly originated at Microsoft in IE. Its imitation by many other
browsers was out of expedience rather than need.
2. While experimenting with the elusive document.all, I ran into a
sort of catch-22, it least with Mozilla. I tried testing
(null == document.all)
Comparison with - null - is not the best test. A direct type-converting
to boolean test will produce false for null and undefined and true for
objects and functions.
to decide if the property exists, and get a warning (in
the Mozilla Javascript console) that the property does not exist. Hm.
Yes, they are berks! They are attempting to apply warning criteria that
make prefect sense when authoring for a known environment in a
non-dynamic language. An no doubt when they write javascript it is for
Mozilla, so they have a known environment and accessing an unimplemented
property would be a mistake. But cross-browser scripting has to exploit
the dynamic nature of javascript and applying an operation that will
type-convert an undefined property into a false boolean value is a
completely valid, normal and (for efficiency at least) desirable
operation.
If you are not writing exclusively for Mozilla ignore Mozilla's
warnings. If you want warnings relating to javascript authoring use
JSLINT.
Is there a robust way to test for a property that may not exist? A
way that does not generate warnings or errors about that
non-existence?
Yes, the - typeof - operator can be used for all testing, it is even
necessary to use it to verify some aspects of the environment, such as
determining if properties refer to primitive values because a
type-converting test will produce false results with empty strings,
numeric zero and boolean false (though no type converting is needed for
that). So - if(typeof pageXOffset == 'number') will tell you that the -
pageXOffset - property is implemented on the browser even when the value
of the number is zero (which it usually is, at least initially). But
notice that the - typeof - test is not one operation it is two, the -
typeof - operation itself followed by string comparison. String
comparison should be fairly quick if the strings don't match, comparing
the first letter will tell you that, but if they do match each letter is
going to have to be compared in turn and that is much more involved.
But when dealing with properties that may be implemented as object or
function a type-converting test will tell you what you want to know in
one quick and simple operation while - typeof - testing would require a
battery of tests to give the same information.
For example, consider the - nextSibling - property of DOM Nodes. The
possibilities are:-
1. It is not implemented, its value is - undefined -, so no attempt
should be made to use it.
2. It is implemented but there is no nextSibling object, the
property value is - null - (or possibly - undefined -, though
that is unlikely), so no attempt should be made to use it.
3. It is implemented and refers to a sibling Node, Possible typeofs
are "object" or "function" because of diverse host environment
implementations. It is safe to interact with the object.
Obviously the reason for testing the - nextSibling - property is to
decide whether to interact with the object. So the - tyoeof - test would
need to see if the returned string was either "object" or "function"
before acting on the node. But (typeof null == "object") so the test
would also have to differentiate between - null - and a real DOM node,
which takes a type-converting test. You can avoid the Mozilla warning by
doing the - typeof - testing first but the result is:-
if(((typeof node.nextSibling == 'object')||
(tyoeof node.nextSibling == 'function'))&&
node.nextSibling){
... // safe to use node.nextSibling.
}
So that is two - typeof - operations (though it could be got down to one
with an assignment to a local variable), two string comparisons and a
type-conversion (not to mention the logical operations) in order to find
out if it is possible to use the node. Compare that with a normal
type-converting test:-
if(node.nextSibling){
... // safe to use node.nextSibling.
}
It differentiates 100% between - null - and - undefined - on one side
and objects and functions on the other. And it is a completely legal
operation in javascript (and all ECMAScript implementations), indeed it
is optimum for the task.
If the authors of Mozilla don't know enough about javascript or browser
scripting to see that they are doing nothing more worthwhile that
burdening their (already often sluggish) browser with generating
meaningless warnings as the result of normal (even advisable) operations
then that is their own look-out. Giving in to their nonsense means
burdening every other browser in existence with inefficient code for no
good reason, and Mozilla is not the only browser in use.
Richard.