Share your views on unobtrusive javascript

A

Animesh K

Hello All:

I came across this topic of UJS (unobtrusive Javascript) recently. I was
wondering if this method is really worth it. Some people suggested using
packages like prototype to use UJS. Other suggested code becomes
lengthy. While others advocate its use saying it leads to a good
separation of content.

My questions:

1) Is UJS worth it, esp will it be more important in the near future?
2) How to begin learning about UJS. Are there any good tutorial like
books to begin? I don't want some theoretical complete reference.

Thank you,
Animesh
 
D

David Mark

Hello All:

I came across this topic of UJS (unobtrusive Javascript) recently. I was
wondering if this method is really worth it.

It isn't a method. It is an umbrella term for various best
practices. Examples:

1. Keep JS out of HTML files to keep content and behavior seperate.
Script pasted into an HTML paged cannot be used with the next page you
write. Paste identical script into the next page and you create a
maintenance problem.

2. Never rely on client side scripting for anything. Write your pages
without JS first. Then use JS to enhance features when appropriate.
Most AJAX sites break this rule.

3. Don't write code forks for specific browsers. Use object and
feature detection instead of sniffing out specific browsers, versions,
etc. You would think this one goes without saying at this point in
time, but many sites break this rule.
Some people suggested using
packages like prototype to use UJS. Other suggested code becomes

Why would you need Prototype to follow these rules? At best it
abstracts the task of attaching listeners to elements (to avoid inline
event handlers), but at worst it abstracts browser sniffing. It is
also bloated with lots of AJAX code that most sites will never need.
lengthy. While others advocate its use saying it leads to a good
separation of content.

My questions:

1) Is UJS worth it, esp will it be more important in the near future?

The methods described above have always been good ideas.
2) How to begin learning about UJS. Are there any good tutorial like
books to begin? I don't want some theoretical complete reference.

Google it.
 
A

Animesh K

David said:
It isn't a method. It is an umbrella term for various best
practices. Examples:

1. Keep JS out of HTML files to keep content and behavior seperate.
Script pasted into an HTML paged cannot be used with the next page you
write. Paste identical script into the next page and you create a
maintenance problem.

Thanks for the reply David. Actually if one is using a Php setup to
generate the files the JS within each PHP file can be edited by editing
just one file. Think something like blog. You can always republish the
blog with a new template.

It isn't really a maintenance problem in that setup. Though I agree with
you about the separation.
2. Never rely on client side scripting for anything. Write your pages
without JS first. Then use JS to enhance features when appropriate.
Most AJAX sites break this rule.

While some features can be enhancements, some AJAX based sites give
applications which cannot be done otherwise (or so I feel). For example,
spreadsheets, or Picasa Photo share. But I get the general picture and
it is an interesting way to think and implement a website.
3. Don't write code forks for specific browsers. Use object and
feature detection instead of sniffing out specific browsers, versions,
etc. You would think this one goes without saying at this point in
time, but many sites break this rule.

This one I agree with.
Why would you need Prototype to follow these rules? At best it
abstracts the task of attaching listeners to elements (to avoid inline
event handlers), but at worst it abstracts browser sniffing. It is
also bloated with lots of AJAX code that most sites will never need.

I googled and found a blog where the guy was worried that UJS is
increasing the amount of code written. So he suggested the use of
Prototype. I personally don't like using Prototypes (they are overkill,
usually). It's like having a cannon to kill a rabbit.
The methods described above have always been good ideas.

Point noted and agreed.
Google it.

Any book?
 
D

David Mark

Thanks for the reply David. Actually if one is using a Php setup to
generate the files the JS within each PHP file can be edited by editing
just one file. Think something like blog. You can always republish the
blog with a new template.

Yes, but sending the same script with every page is a waste of
bandwidth.
It isn't really a maintenance problem in that setup. Though I agree with
you about the separation.




While some features can be enhancements, some AJAX based sites give
applications which cannot be done otherwise (or so I feel). For example,
spreadsheets, or Picasa Photo share. But I get the general picture and

You can certainly create a spreadsheet without client side scripting.
Same for a photo-sharing application. And the point is that many AJAX
sites display script-only interfaces even with scripting disabled (eg
arrows for dropdown menus that never appear.) That's just stupid.
it is an interesting way to think and implement a website.




This one I agree with.

Prototype users will suggest you use Prototype for everything. They
are married to it, so it is in their interest to keep it in fashion.
I googled and found a blog where the guy was worried that UJS is
increasing the amount of code written. So he suggested the use of
Prototype. I personally don't like using Prototypes (they are overkill,
usually). It's like having a cannon to kill a rabbit.

Prototype and other libs like it are massive overkill, especially when
you consider that most sites do not need AJAX at all. I don't think I
have ever seen Prototype without Scriptaculous (sp?) beside it and
that is something like 150K added and often for nothing more than a
few special effects. That's almost as stupid as using Flash.
Point noted and agreed.





Any book?

Not that I know of.
 
D

d d

David said:
3. Don't write code forks for specific browsers. Use object and
feature detection instead of sniffing out specific browsers, versions,
etc. You would think this one goes without saying at this point in
time, but many sites break this rule.

I think this one falls into the same camp as the "eval is evil" mantra.
It's just not true that you don't ever need to fork for browsers, just
like using eval isn't always evil (sometimes it is necessary).

The same goes for browser forking. 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 from an iframe into a parent page, Safari
can sometimes result in that code being inaccessible 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.

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.

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. 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, then that's slowing down browsers that don't need
slowing 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.

5. Various other issues with media players and browser combinations.

6. Various issues with Flash external interface not creating the objects
properly which they use to script into Flash, on IE only. If anyone is
considering using external interface instead of getURL or FSCommand,
google the hell out of it first and see if the problems are acceptable.

7. Various browser versions don't properly support transparent Flash.

8. Mac IE has all kinds of issues, too numerous to mention.

9. Various plugins won't work on Opera when it's spoofing itself as
other browsers.

10. Firefox 1.0.x has all kinds of issues and is best avoided (default
to a "classic" version of a page).

I could go on, really I have more, but as you can see, there are many
many reasons why browser sniffing can become essential. I didn't even go
into the different CSS support problems, and several of those points
above are 'various issues' that I haven't even listed out in full.

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.

~dd
 
R

RobG

I hate the term "UJS", it's a complete misnomer. What is really meant
is using javascript to add handlers at the client which, as you said
elsewhere, it is hardly any different to doing it at the server before
sending it.

Yes, but sending the same script with every page is a waste of
bandwidth.

Not really. Client-applied handlers are often dependent on elements
having specific IDs or classnames, adding a simple handler directly to
the HTML can often be less code. The body of functions can usually be
delivered in a single js file that is cached.

Client-applied handlers are also often strictly tied to a certain
document structure - it is very common to see functions that go up and
down the DOM looking for a specific structure to do stuff. From that
perspective, the idea of separating script from layout is completely
contradicted.


[...]
You can certainly create a spreadsheet without client side scripting.

I think the point is that it is very hard to make a usable corporate
intranet application without serious scripting. A big issue is that
many intranet developers are Windows developers who think in terms of
Windows applications and write really appalling browser applications.


[...]
Prototype users will suggest you use Prototype for everything. They
are married to it, so it is in their interest to keep it in fashion.

I agree with that. They think that since you've downloaded it once and
it's cached, what's the issue? But many sites use it for very trivial
functions that could have been written in a few lines, yet visitors are
forced to suck down maybe 300kB of libraries to do it.

Prototype and other libs like it are massive overkill, especially when
you consider that most sites do not need AJAX at all. I don't think I
have ever seen Prototype without Scriptaculous (sp?) beside it and
that is something like 150K added and often for nothing more than a
few special effects. That's almost as stupid as using Flash.

I love Flash - I use FlashBlock to get rid of all Flash content :) I
wish I could just as effectively get rid of annoying scriptaculous effects.
 
D

David Mark

I think this one falls into the same camp as the "eval is evil" mantra.
It's just not true that you don't ever need to fork for browsers, just
like using eval isn't always evil (sometimes it is necessary).

The same goes for browser forking. 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 from an iframe into a parent page, Safari
can sometimes result in that code being inaccessible 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.

My solution to that would be to not use an iframe.
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.

Then that version is broken beyond belief and I wouldn't worry about
supporting it at this time. As for preventDefault, what happens if
you return false from the event handler?
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. Yes that's true, but

Yes. For an interactive Flash movie that is true.

if you
have to wait for the page to be complete before you can add a new JS
file to the DOM, then that's slowing down browsers that don't need
slowing down.

You only have to do that when serving XHTML, with HTML you would just
document.write the object tag(s) from an external file. I wouldn't
insert a JS into the DOM, I would insert the object tag(s) when the
DOM is ready. And if Windows IE is all that you are worried about,
use IE conditional comments.
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.

Flash just isn't worth supporting for this and many other reasons.
5. Various other issues with media players and browser combinations.

Like what?
6. Various issues with Flash external interface not creating the objects
properly which they use to script into Flash, on IE only. If anyone is
considering using external interface instead of getURL or FSCommand,
google the hell out of it first and see if the problems are acceptable.

I say don't use Flash at all, but if you must and it must communicate
with your JS, don't use external interface. But if it is an IE-only
problem (the memory leak issue?) that you refer to, IE conditional
comments are the way around it.
7. Various browser versions don't properly support transparent Flash.

A pattern is emerging here. Don't use transparent Flash.
8. Mac IE has all kinds of issues, too numerous to mention.

That browser is dead and buried. Anybody still using it will have
problems with virtually every site on the Internet.
9. Various plugins won't work on Opera when it's spoofing itself as
other browsers.

Then those plugins are defective. Don't use them.
10. Firefox 1.0.x has all kinds of issues and is best avoided (default
to a "classic" version of a page).

Presumably Firefox users are sophisticated enough to upgrade. How old
is that version?
I could go on, really I have more, but as you can see, there are many
many reasons why browser sniffing can become essential. I didn't even go
into the different CSS support problems, and several of those points
above are 'various issues' that I haven't even listed out in full.

You don't want to get into CSS hacks either. Those are as bad as
browser sniffing and guaranteed to sacrifice forward compatibility for
backward.
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.

In short I say:

1. Don't use Flash.
2. Set reasonable limits on what outdated browsers are to be
supported. For instance, is anybody still supporting Netscape 4.7?
3. Validate everything and test thoroughly on as many devices and
browsers as possible.

After that, let the chips fall where they may.
 
D

David Mark

Not really. Client-applied handlers are often dependent on elements
having specific IDs or classnames, adding a simple handler

Of course.

directly to
the HTML can often be less code. The body of functions can

That depends on how many elements are in the structure and how many
pages share the same structure.

usually be
delivered in a single js file that is cached.

Client-applied handlers are also often strictly tied to a certain
document structure - it is very common to see functions that go up and
down the DOM looking for a specific structure to do stuff. From that
perspective, the idea of separating script from layout is completely
contradicted.

It would have to be a pretty poorly conceived script to rely on the
layout to work. I can't think of such an example.
[...]
You can certainly create a spreadsheet without client side scripting.

I think the point is that it is very hard to make a usable corporate
intranet application without serious scripting. A big issue is

Depends on what it has to do.

that
many intranet developers are Windows developers who think in terms of
Windows applications and write really appalling browser applications.

I agree that most Intranet (and Internet) developers are incompetent.
Windows developers are notoriously bad as well. Most don't think at
all (they just copy and paste sample code.)
[...]
Prototype users will suggest you use Prototype for everything. They
are married to it, so it is in their interest to keep it in fashion.

I agree with that. They think that since you've downloaded it once and
it's cached, what's the issue? But many sites use it for very trivial
functions that could have been written in a few lines, yet visitors are
forced to suck down maybe 300kB of libraries to do it.

Right. And then there are those misleading charts that show the
wonders of http compression. As if that had anything to do with the
issue!
I love Flash - I use FlashBlock to get rid of all Flash content :) I
wish I could just as effectively get rid of annoying scriptaculous effects.

You can! Disable JavaScript.
 
R

Richard Cornford

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.
result in that code

Which code? The code that does the injecting?
being inaccessible

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.
I could go on,

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

Richard Cornford

Animesh said:
I came across this topic of UJS (unobtrusive Javascript) recently.
I was wondering if this method is really worth it.

Design decisions should not start with imposing arbitrary restrictions
on the outcome. You have something to achieve and you have a context in
which to achieve it. It is ludicrous to pre-suppose that any single
approach will always be the best approach to achieve anything and
everything in all contexts. Promises of universal panaceas should be
regarded with extreme suspicion.
Some people suggested using packages like prototype to use UJS.

Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not the
best source of advice on designing systems that use javascript.
Other suggested code becomes lengthy.

Doesn't Prototype.js avoid becoming lengthy by starting off lengthy?
With the bonus of it's being inefficient itself and encouraging
(sometimes forcing) people to write very inefficient code in order to
use it.
While others advocate its use saying it leads to a good separation of
content.

Separating presentation, content and mechanism(s), in the perception of
a project as seen by its developers/maintainers, is an extremely
valuable/rewarding characteristic of well designed system architecture.
"Unobtrusive Javascript" does not inherently provide this in the areas
of an architecture where it has an influence, could not contribute to
proper separation outside the areas of its influence (on the server),
and is a very long way from being the only possible means of achieving
that separation. Just putting the javascript into an external file, of
itself, is only separation in the most superficial sense. And the
browser's view of separation is an irrelevance compared to the
developer/maintainer's perception of it.
My questions:

1) Is UJS worth it,

It is worth it if in the context of the whatever it is that is to be
achieved the (any) tangible benefits it brings exceed any negative
impact it may have. It is a design decision, and so tied to the specific
context.
esp will it be more important in the near future?

There is nothing new here except a label. That label has been attached
to things that have been possible virtually since the dawn of browser
scripting, and have been in common use over that time.
2) How to begin learning about UJS.

Learn to design/write cross-browser (as opposed to multi-browser)
scripts and when you have don that you will know everything you need to
know both the implement "unobtrusive scripting" and decided where its
use is appropriate.
Are there any good tutorial like books to begin?

There are no good javascript books. David Flanagan's "JavaScript: The
Definitive Guide" (ISBN:0-596-10199-6) is the least bad javascript book
(by a very wide margin), but you won't find the techniques for
"unobtrusive javascript" grouped under that label in it.

(Incidentally, one of the tell-tale characteristics of a very bad
javascript book is that the publishes make a sample chapter available
that has no technical content. Something like and introduction to
javascript, or its history. That makes it difficult to state how bad any
particular book is without getting hold of a copy (which is probably
what the publishers want). While if a technical chapter is available
someone who knows what they are doing can look at it and say, for
example (and based upon a particular book I have in mind, no names but
it has "Advanced" in the title) "60% of the factual statements made are
false, the code is inept and promotes approaches that are hard to
maintain, and the design advice varies from the poor to the
catastrophic: it is average for a javascript book".)
I don't want some theoretical complete reference.

Probably we all started off learning javascript from books. As you learn
more, and try more, one of the things you learn is how bad those books
were. At this point nobody is going to start looking at tutorial books
that attempt to round up the techniques we have been using for years,
without being paid to do so. And that is assuming such books exist.

That leaves you with a problem; the people reading such books are doing
so precisely because they don't know enough to judge them in the wider
context, and the people who could make the judgment are not motivated to
even look at those books.

Richard.
 
D

d d

Richard said:
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.

Well, your reply basically boils down to two major arguments. One is
that there's no need to sniff (and I accept that I didn't add any proof
that there is a reason). The other argument being that it's impossible
to sniff accurately.

Just because I didn't go into great detail about the problems, doesn't
mean they aren't real. I didn't want to write 250 lines that nobody
would read. I'll just say this. Try going to either the Firefox or
Safari Bugzilla DB's and check out the numerous problems that are
specific to a particular version of the browser, and/or a specific
version of a plugin. Whether you or I consider Flash to be something
that shouldn't be used, that doesn't mean it won't be. I don't get
involved in any of the site design decisions, but I have to live with
them. If I know that a specific version of a plugin will crash a
specific version of a browser if used in a certain way, then it would be
irresponsible to NOT sniff for those two conditions and take action to
avoid the logged browser crash.

Regarding the point that it's impossible to sniff accurately. Well
that's just not true. You can sniff very accurately for default
browsers, and the default user agent string is the vast majority. OK you
can make Netscape 8 pretend to be either IE or Firefox, you can make
Opera and Safari pretend to be just about anything. If those spoofed
user agent strings cause a mis-sniff, then it's their own fault. If you
dress up as a woman and do it very well, you shouldn't be surprised if
guys hit on you ;-) If I'm a user that's sufficiently advanced enough
to change my user agent string then I know what might happen. For all
those default browsers, not only is it possible, it's very easy.
Besides, it's also very easy to detect browsers that are spoofing. All
my sniffer code doesn't get fooled. Opera and Safari and NS8 are all
detected properly, regardless of what spoof mode they're in.

~dd
 
P

Peter Michaux

Hello All:

I came across this topic of UJS (unobtrusive Javascript) recently. I was
wondering if this method is really worth it. Some people suggested using
packages like prototype to use UJS. Other suggested code becomes
lengthy. While others advocate its use saying it leads to a good
separation of content.

My questions:

1) Is UJS worth it, esp will it be more important in the near future?
2) How to begin learning about UJS. Are there any good tutorial like
books to begin? I don't want some theoretical complete reference.

There is still a major problem with implementing UJS: the
window.onload problem. I investigated this in depth and wrote
something long about it too.

<URL: http://peter.michaux.ca/article/553>

Peter
 
R

Richard Cornford

Well, your reply basically boils down to two major arguments.
One is that there's no need to sniff (and I accept that I
didn't add any proof that there is a reason). The other
argument being that it's impossible to sniff accurately.

You weren't reading very accurately. I said that as it is impossible to
accurately determine the browser or its version and perceived need to do
so is an irrelevance.
Just because I didn't go into great detail about the problems,
doesn't mean they aren't real.

But it does man that you cannot be shown how you could avid your
perception of a need to browser sniff by learning how you might identify
the tests that will give you the answers you really need.
I didn't want to write 250 lines that nobody would read.

250 lines of text would be pointless. 250 lines of code that
demonstrated your perception of a need would be something else. It might
make your point for you, or it might be the starting point of your
learning how the rest of us are happily getting by without browser
sniffing.
I'll just say this. Try going to either the Firefox or Safari Bugzilla
DB's and check out the numerous problems
that are specific to a particular version of the browser,
and/or a specific version of a plugin. Whether you or I
consider Flash to be something that shouldn't be used, that
doesn't mean it won't be. I don't get involved in any of the
site design decisions, but I have to live with them. If I know
that a specific version of a plugin will crash a specific
version of a browser if used in a certain way, then it would be
irresponsible to NOT sniff for those two conditions and take
action to avoid the logged browser crash.

So rather than narrowing down to the specifics of a particular case and
letting us test the proposition that your examples cannot be tested for
you are becoming even more vague and pointing at the entire bug
databases of two browsers.

Browsers have bugs. They always have and the always will. Yet the
Internet exists, mostly works, and people make a living writing code for
it that does not get involved with browser sniffing.
Regarding the point that it's impossible to sniff accurately.
Well that's just not true.

Your saying that something is not true does not make it so. There are
only two browser-sniffing techniques: UA string testing and object
inference. Both have flaws that render them incapable of accurately
discriminating web browsers and their versions.
You can sniff very accurately for default browsers,

What is "the default browser"?
and the default user agent string is the vast majority.

Is "the vast majority" of what?
OK you can make Netscape 8 pretend to be either IE or
Firefox, you can make Opera and Safari pretend to be
just about anything.

You can make IE pretend to be just about anything as well, but the real
problems come with the many browsers that pretend to be one of the major
browsers (usually IE) by default.
If those spoofed user agent strings cause a mis-sniff,

There you go. It is an unreliable technique, and nothing can be done to
stop that.
then it's their own fault.

No it is not. The HTTP specification makes it very clear that the User
Agent (and so the browser's userAgent string) is not a source of
information; that is it essentially an arbitrary sequence of that
doesn't even have to be the same for any two consecutive requests.
Predicating a strategy on treating something that is not a source of
information as if it was a source of information is an obvious folly,
and if you do that the consequences are your fault. The User Agents are
conforming with the pertinent specification whatever they as their User
Agent headers.
If you dress up as a woman and do it very well,
you shouldn't be surprised if guys hit on you ;-)

You have not understood why it is normal for web browser's UA strings to
spoof other browser's UA strings.
If I'm a user that's sufficiently advanced enough to change my user
agent string then I know what might
happen.

Don't blame the user for the consequences of your mistakes. Your
'sufficiently advanced user' is quite capable of understanding that the
line they must not cross is violating HTTP. If they do that they should
have every expectation of things not working properly, but if they don't
then it is some other fool's fault when things go wrong.
For all those default browsers, not only is it possible,
it's very easy.

All you re saying is that you can distinguish a default configuration of
one common browser from a default configuration of another common
browser. And you can do that, but as you cannot know that what appears
to be a default configuration of a common browser actually is a default
configuration of that browser the ability to distinguish between them is
not the ability to identify them. It is accurately identifying the
browser and/or its version that is impossible.
Besides, it's also very easy to detect browsers that are
spoofing.

Is it? how would you discriminate NetFront or IceBrowsr from IE?
All my sniffer code doesn't get fooled.

I know where I would be placing my money.
Opera and Safari and NS8 are all detected properly, regardless
of what spoof mode they're in.

You are deluded.

Richard.
 
D

d d

Richard said:
You weren't reading very accurately. I said that as it is impossible to
accurately determine the browser or its version and perceived need to do
so is an irrelevance. snip
You are deluded.

OK, I give up.

At least I'm in good company though. I'm sure you'll agree that Google,
Yahoo, MSN and AOL are some of the largest tech companies in the world
and attract some of the finest developer minds to work for them. Are
they all deluded too? They're also foolishly sniffing for browsers via
the useragent, even though it's impossible to accurately determine the
browser, and it's pointless trying to do so.

Douglas Crockford, please explain why the YUI library is sniffing for
browsers. Richard says it can't be done, and doesn't need to be.

I believe you Richard, that the code you write can be done without
sniffing for browsers. I've written lots of things that didn't need it.
In my world though (and clearly in the world occupied by the code from
Google, Yahoo, MSN and AOL) there is a need for it, and it works on over
99.9% of browsers. It's a fact that's proven by the traffic logs from
web servers that 99.9% of visiting browsers are identified to be the
main browsers mentioned below. Of all the logs I've looked at, you don't
even see Opera or Safari in spoof mode get listed. People simply aren't
doing it.

btw, I never heard of NetFront or IceBrowser and unless they raise their
heads above the level of 0.1% browser market share, I doubt I'll
encounter them. If you use an obscure browser, or one with a spoofed
useragent, then what happens to you as you browse the web is your own
fault. Most web pages are written for the majority of browsers and
playing with bleeding edge tech, you can expect less than ideal results.
We're writing javascript that meets the vast majority, and I don't
mean an 80% majority, I mean > 99.9%.

What exactly is wrong with this pseudo code ?

if useragent has opera then browser is opera
else if useragent has safari then browser is safari
else if useragent has flock then browser is flock
else if useragent has firefox then browser is firefox
else if useragent has ie then browser is ie
else if useragent has netscape then browser is netscape
else if useragent has mozilla then browser is mozilla
else browser is unknown and gets a "classic" simple page

Sniffing for the two most popular spoofers gets them identified first,
thereby disregarding their spoofery. Searching for Flock (a variant of
Firefox) means it doesn't get seen as firefox. Searching for Firefox
before netscape means firefox doesn't get identified as netscape. Then
comes IE (which also catches netscape 8 in IE mode, but that's what we
want, because it is running an IE instance). Then comes netscape, so it
doesn't get identified as mozilla. Finally a mozilla check last (because
so many of the browsers above also have mozilla in their useragent).

I know you're going to say that using the useragent itself isn't a
reliable way of trying to determine the browser. All I can say (again)
is that it works for me (and Google, and Yahoo, and MSN and AOL)...

~dd
 
R

RobG

OK, I give up.

At least I'm in good company though. I'm sure you'll agree that Google,
Yahoo, MSN and AOL are some of the largest tech companies in the world
and attract some of the finest developer minds to work for them. Are
they all deluded too?

Yes. eBay recently told me that I was using Safari 1.0 and to update
it to the latest version - I was actually using Safari 3.0. I let
them know and within a day or so they had it fixed, but I wonder how
many users saw that message and didn't know what to do about it? Or
blamed Safari? 3.0 had been out for about a month at least.

They're also foolishly sniffing for browsers via
the useragent, even though it's impossible to accurately determine the
browser, and it's pointless trying to do so.

Yes, see above. I recently tried to use Google Groups with Safari
1.3, it fails in "tree view". Cleary either their sniffing fails to
identify it or they don't bother to respond if they do. Either way,
my opinion of Google developers is not very high in regard to code
quality as evidenced by their javascript skills.


[...]
I believe you Richard, that the code you write can be done without
sniffing for browsers. I've written lots of things that didn't need it.
In my world though (and clearly in the world occupied by the code from
Google, Yahoo, MSN and AOL) there is a need for it, and it works on over
99.9% of browsers. It's a fact that's proven by the traffic logs from
web servers that 99.9% of visiting browsers are identified to be the
main browsers mentioned below.

That is not proof. You will likely never know from such logs whether
they correctly identified the browser or not. All you can do is some
kind of test of UA string to feature set and see if matches what you
think it should. If it doesn't, does that mean the browser is
spoofing or you messed up the UA string/feature set match?

Of all the logs I've looked at, you don't
even see Opera or Safari in spoof mode get listed. People simply aren't
doing it.

btw, I never heard of NetFront or IceBrowser and unless they raise their
heads above the level of 0.1% browser market share, I doubt I'll
encounter them.

There are about to be billions of mobile devices running web
browsers. Of those that identify as a "major" browser, how many will
actually have all the features of their bigger cousin? What is the
leading mobile browser? How many need to be sniffed out to get 99.9%
of mobile users?

Enough for now, I don't want to sound like I'm getting on your case,
I'm just in a bit of a rush! :)

Cheers,
 
D

d d

RobG said:
Yes. eBay recently told me that I was using Safari 1.0 and to update
it to the latest version - I was actually using Safari 3.0. I let
them know and within a day or so they had it fixed, but I wonder how
many users saw that message and didn't know what to do about it? Or
blamed Safari? 3.0 had been out for about a month at least.

Well, ebay has let the side down there. I'm not surprised though. If you
look at the useragent for Safari 1.3 it identifies itself with a real
number like Safari/312.6 (that's what my 1.3 shows). Whereas my 3.0
shows itself as Safari/522.11.3. I bet ebay's parsing read that as 11.3.
Yes, see above. I recently tried to use Google Groups with Safari
1.3, it fails in "tree view". Cleary either their sniffing fails to
identify it or they don't bother to respond if they do. Either way,
my opinion of Google developers is not very high in regard to code
quality as evidenced by their javascript skills.

Yeah I really regretted adding Google to my list of high profile sites
that sniff. They suck big time. I can't view their google groups without
getting numerous errors if I go there with IE. They really need a course
on defensive programming.
Enough for now, I don't want to sound like I'm getting on your case,
I'm just in a bit of a rush! :)

I hope I haven't given the impression that my code is littered with
browser logic like if(IE)attachEvent(bla);else addEventListener(bla); I
use feature detection in all places possible. I also avoid eval as much
as possible. However, when I do know of cases where taking a particular
feature path must be avoided for a specific browser (despite the fact
that it will pass a feature test), then I'll use my useragent-sniffed
booleans to let me avoid that.

~dd
 
A

Animesh K

Yes, but sending the same script with every page is a waste of
bandwidth.

Agreed.


You can certainly create a spreadsheet without client side scripting.
Same for a photo-sharing application. And the point is that many AJAX
sites display script-only interfaces even with scripting disabled (eg
arrows for dropdown menus that never appear.) That's just stupid.

That's an interesting thought. So how about showing "all the script
related buttons" with document.onload handler? Will document write be a
better option? Or will it be better to use "display: none" attributes?

Prototype users will suggest you use Prototype for everything. They
are married to it, so it is in their interest to keep it in fashion.

I know and it sucks.
Not that I know of.

I googled and came across one. But reviewers say that his codes don't
work properly.

http://onlinetools.org/articles/unobtrusivejavascript/
 
A

Animesh K

RobG said:
I hate the term "UJS", it's a complete misnomer. What is really meant
is using javascript to add handlers at the client which, as you said
elsewhere, it is hardly any different to doing it at the server before
sending it.

Can you explain the viewpoint more? The misnomer part.
Not really. Client-applied handlers are often dependent on elements
having specific IDs or classnames, adding a simple handler directly to
the HTML can often be less code. The body of functions can usually be
delivered in a single js file that is cached.

Client-applied handlers are also often strictly tied to a certain
document structure - it is very common to see functions that go up and
down the DOM looking for a specific structure to do stuff. From that
perspective, the idea of separating script from layout is completely
contradicted.


And explain this above point more as well. I am a bit lost on the
"contradicted" part.

I love Flash - I use FlashBlock to get rid of all Flash content :) I
wish I could just as effectively get rid of annoying scriptaculous effects.


Use Noscript or Adblock in firefox to filter certain scripts that you
don't like.
 
R

RobG

Animesh said:
Can you explain the viewpoint more? The misnomer part.

Properly applied handlers only add a function call to the value of an
attribute in the HTML. So-called unobtrusive scripts usually rely on
elements having an ID or class attribute that otherwise would not have
been needed, so one bit of markup is replaced by another.

And explain this above point more as well. I am a bit lost on the
"contradicted" part.

The contradiction comes when a handler is dependent on the document
structure. You often see scripts that apply effects (e.g. hiding,
showing, sliding up or down) that go looking for the first div parent or
first ul parent or such. In those cases, you must ensure that the
handler is on the right element and within the right structure,
otherwise it all falls apart.

Add to that the requirement that to identify the right element to start
the up/down/next search also requires an appropriate ID or class on that
element and you've got to ask yourself: why not just apply the handler
directly?

I'm not criticising the technique as such, only the claim that applying
handlers dynamically at the client rather than inline on the server
abstracts markup from code. Separate physically, yes. Abstract, no -
the handlers still need to end up on the right elements.

Use Noscript or Adblock in firefox to filter certain scripts that you
don't like.

I already use Adblock, but you can't block scripts willy-nilly - much
better to turn off script support completely.
 
A

Animesh K

RobG wrote:
Properly applied handlers only add a function call to the value of an
attribute in the HTML. So-called unobtrusive scripts usually rely on
elements having an ID or class attribute that otherwise would not have
been needed, so one bit of markup is replaced by another.

That's a very good point. Thank you.
The contradiction comes when a handler is dependent on the document
structure. You often see scripts that apply effects (e.g. hiding,
showing, sliding up or down) that go looking for the first div parent or
first ul parent or such. In those cases, you must ensure that the
handler is on the right element and within the right structure,
otherwise it all falls apart.

Add to that the requirement that to identify the right element to start
the up/down/next search also requires an appropriate ID or class on that
element and you've got to ask yourself: why not just apply the handler
directly?

Ditto, nice point here too.
I'm not criticising the technique as such, only the claim that applying
handlers dynamically at the client rather than inline on the server
abstracts markup from code. Separate physically, yes. Abstract, no -
the handlers still need to end up on the right elements.

Agreed.


I already use Adblock, but you can't block scripts willy-nilly - much
better to turn off script support completely.


I meant adblock for flash and noscript for javascript. There are
websites where JS is handy.

Best,
A
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top