d said:
I think this one falls into the same camp as the "eval is evil"
mantra.
The people chanting the '"evel is evil" mantra' are always in a position
to point to (hundreds of) thousands of examples where someone seeing
that - eval - exists have then gone on to employ it in a way that is
stupid, pointless, futile or dangerous, and then some of them trying to
defend their use of - eval - in a way that demonstrates that they really
had no idea what they were doing. The idea is that "eval is evil"
because it lets people carry on writing obscure, hard to maintain, and
sometimes absolutely silly code when they could be learning to write
javascript well.
It is an extreme position, and probably more extreme than it needs to
be, but it has also reaped rewards for the world of browser scripting.
Go back 5 years and look at answers posted on comp.lang.javascript and
you will see a constant procession of inexperienced javascript authors
trying to 'help' by posting code littered with unnecessary uses of -
eval -. So many that at the time I thought we could have a competition
for the month's "most futile use of the - eval - function" and have at
least half a dozen good nominations each month.
(A "futile" use of - eval - would be something like:-
var y = eval("document.getElementById('xxx')");
- or (worse):-
var y = eval(document.getElementById('xxx'));
- the second being the winner of "most futile" because whenever its
argument is not a string the - eval - function just returns its
argument, so in that case no code is even evaluated)
That situation has changed and currently you hardly see anyone proposing
anything nearly so stupid. Could it be that 5 years of people taking a
slightly extreme position towards - eval - might have improved the
standard of javascript knowledge and authoring globally?
It's just not true that you don't ever need to fork
for browsers,
You have not understood the position. Whether you ever need to fork code
for a particular browser or not is irrelevant. The simple truth is that
there is no technique arable that can accurately identify a browser or
its version. That is just impossible, and your perception of a need to
do so will not make it possible.
The reason for proposing that people not attempt browser sniffing as a
criteria for branching code is that it is an obvious mistake to
predicate a script design upon an ability to do something that is know
to be impossible to achieve. The best that can come out of that are
unreliable scripts that just about function with a tiny handful of known
browsers in their default configurations, and just fall apart when
exposed to anything else (where "anything else" often includes the next
release of one of the "known browsers" (so unreliable code with ongoing
maintenance costs)).
just like using eval isn't always evil (sometimes it is
necessary).
The use of the -eval - function is never necessary, it is just that its
use is sometimes expedient (the effort needed to avoid its use in some
circumstances are disproportional (particularly if they involve
implementing the rest of javascript in javascript so you can turn a code
string into something that can be executed)).
The same goes for browser forking.
But if browser sniffing cannot identify browsers and their versions
accurately seeing a need to do so speaks of a design fault.
I could list probably a dozen cases where browser forking is
absolutely necessary (and I'm sure you'll ask me to ;-). Here are a
few cases that I've had to fork for:
1. When trying to inject code
Define "inject code".
from an iframe into a parent page, Safari can sometimes
Ah, and there is the word "sometimes". Being relentlessly mechanically
logical it is not in the nature of computers to "sometimes" do one thing
and then "sometimes" do something else. Given the same state and the
same input computers always produce the same output, they have no
choice. What "sometimes" means is that you have not analysed the
situation to the point of pinning down the cause and effect relationship
that is pertinent to your situation. And without knowledge of that cause
and effect relationship how do you expect to be take seriously when you
assert that it cannot be tested for, or that the need to test for it
cannot be avoided entirely.
Which code? The code that does the injecting?
Where is it inaccessible from?
unless you write the code to the script element using s.innerHTML.
This is a known workaround and can't be sniffed for in any way
other than by browser.
Haven't you just outlined the feature test that could be done here? You
try to "insert" the code and then you try to access it, and if you
cannot access it you are in a situation where the inserted code is
inaccessible and can try something else. Though once you have pinned
down the real cause and effect relationship a better test probably could
be devised.
2. Although Safari 1.3 supports the preventDefault and
stopPropagation methods of an event (i.e. it has them and
you can call them), they don't do anything. It's as if
they're still stub functions that were never implemented.
And yet a considerable volume of event driven javascript works
absolutely fine on Safari (including old versions). Could it be that you
have elected to do something that is brining you up against this issue
that you could just stop doing?
3. EOLAS patent dispute issue. If you're writing an object/embed
tag for Flash into the page on IE6 or IE7, you need to write it
from an external javascript file. OK, you might say, simply do
that for all browsers and those that don't need it won't complain.
And strangely that is what most have elected to do.
Yes that's true, but if you have to wait for the page to be
complete before you can add a new JS file to the DOM,
Why add a new script element to the DOM? All you have to do is put a
SCRIPT element at the point where you want the OBJECT element, that
imports a script file that - document.write -s your OBJECT/EMBED mark-up
straight into the context where it is wanted.
then that's slowing down browsers that don't need slowing down.
If you insist on needlessly jumping through hoops to achieve something
then that will slow things down.
4. Firefox 2.0.0.2 had issues that would make it crash the
browser when using Flash objects. They had to work quickly
to release 2.0.0.3 to fix this.
Doesn't Firefox automatically check for updates by default?
5. Various other issues with media players and browser
combinations.
The question is not whether issues exist but whether they are issues
that cannot be directly tested for. To mark that determination it is
necessary to be specific about what the issues are and how you go about
provoking them.
6. Various issues with Flash external interface not creating the
objects properly which they use to script into Flash,
<snip>
Are you really asserting that the consequences of "not creating the
objects properly" cannot be feature tested?
Still, the general advice concerning Flash is that if you want to use
Flash at all you should do everything (the whole site) in, and inside,
the Flash, or not use Flash at all.
7. Various browser versions don't properly support transparent Flash.
So what?
8. Mac IE has all kinds of issues, too numerous to mention.
The question is not whether issues exist but whether they are issues
that cannot be directly tested for. To mark that determination it is
necessary to be specific about what the issues are and how you go about
provoking them.
9. Various plugins won't work on Opera when it's spoofing
itself as other browsers.
You realise that that means that the authors of those plugins have
foolishly followed the browser sniffing line and ended up writing
something unreliable that falls over at its first exposure to anything
outside of its authors limited experience. That hardly represents a
good contribution to an argument in favour of branching javascript based
upon browser sniffing.
10. Firefox 1.0.x has all kinds of issues and is best
avoided (default to a "classic" version of a page).
The question is not whether issues exist but whether they are issues
that cannot be directly tested for. To mark that determination it is
necessary to be specific about what the issues are and how you go about
provoking them.
Maybe, but you will not get anywhere useful posting vague allegations
without the specifics or the test cases. Experience says that 90% of the
things that people assert require browser sniffing are actually amenable
to feature testing once they have been precisely pinned down, and the
rest can be designed out of the system.
really I have more, but as you can see, there are many many reasons
why browser sniffing can become essential.
And, even if true, that would not change the fact that browser sniffing
is not capable of accurately identifying browsers or their versions.
As I said at the start, the issue is similar to the eval is
evil situation. It's wrong to use eval when not needed, and
it's wrong to sniff for the browser when it's not needed. Simply
checking for the existence of properties (e.g. offsetWidth, clientY)
or of certain methods (getElementById, addEventListener) is often
all that's needed, but in a lot of cases it isn't.
You have not demonstrated a single case where browser sniffing is
necessary. Vague descriptions are not a demonstration of the
impossibility of feature testing. And even if you had you cannot get
round the fact that you cannot accurately identify browsers or their
versions with browser sniffing. And identifying a need to do the
impossible still would not render it possible.
With browser sniffing you can ask the question but the answer given by
code is not necessarily the correct answer (and there are no technical
grounds for expecting it to be the correct answer).
With properly designed feature detecting code you always get the correct
answer to the questions you ask, but you have to absolutely pin down the
question you should be asking or the correct answer to the question
asked may not suite the decision made with it.
So it is usually an inability to pin-down the question that should be
being asked that leads people to promote the notion of browser sniffing,
regardless of the fact that it is known to be an impossible task to do
accurately.
Richard.