Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > FAQ Question: How do I detect Opera/Netscape/IE

Reply
Thread Tools

FAQ Question: How do I detect Opera/Netscape/IE

 
 
Garrett Smith
Guest
Posts: n/a
 
      06-01-2009
8.6 _How do I detect Opera/Netscape/IE_?

The navigator object contains strings which
specify the browser and version; however, this is in general not
very genuine. Mozilla (and therefore Netscape 6+) allows this to
be freely set, and Opera and IE allow it to be modified. There
are also at least 25 other javascript capable browsers with
their own strings here.

Generally though, you don't need to identify which browser is
being used. There are alternative techniques, but which one you
choose depends on why you want to redirect browsers. If it's to
offer different CSS stylesheets, then <URL:
http://w3development.de/css/hide_css_from_browsers/ >
shows many techniques. For Scripting, _object_ detection
is a better method to use.
<URL: http://www.quirksmode.org/js/support.html >
It is also known as feature detection.

Object/feature detection means checking that the object you wish
to use is supported by the browser before using it. This means
that you don't need to know what browsers support what methods,
and your code will automatically be usable on any browser that
can execute it.


if (document.getElementById &&
document.getElementById('el') &&
document.getElementById('el').style ) {
// We know that this browser supports getElementById and has
// a style object, so we can set a style property.
document.getElementById('el').style.color = "red";
}


Browser bugs can often be detected and overcome in similar ways.

<URL:
http://developer.mozilla.org/en/docs...Platform_Pages
>

<URL: http://jibbering.com/faq/faq_notes/n...er_detect.html >
<URL: http://dev.opera.com/articles/view/u...ity-detection/ >
<URL:
http://developer.apple.com/internet/...detection.html >


==========================================

Commentary:

The entry links to the quirksmode.org article:
http://www.quirksmode.org/js/support.html

While well intentioned, this article has some information that is
factually false and would likely mislead someone learning javascript. I
found in that article:

| if (window.focus)
| means: "If the focus method is supported", while this code
| if (window.focus())
| means:
| "If you can put the focus on the window" and assumes that focus
| is supported.

Both statements are wrong.

Regarding the first statement, I am concerned with the possibility of a
browser to be configured to disallow scripts to focus windows, yet have
a focus property.

Regarding the second statement, that is just dead wrong. The
window.focus method call should return undefined where supported and the
|if| statement would be false.

He also calls document.images and "array". It is not. It is an
HTMLCollection in standards-compliant browsers.

I have added a link to Hallvord R.M. Steen's "Object Detection". The
article does not mention ToBoolean errors on ActiveX objects. I sent an
email to Hallvord and asked him to add something about that.

Rearding the the FAQ, it is not to the point enough.

| Generally though, you don't need to identify which browser is being
| used. There are alternative techniques, but which one you choose
| depends on why you want to redirect browsers.

Not to the point. Redirect browsers? No, that is not usually why browser
detection is used. "Alternative" techniques? I'd rather think of
capability detection as a "mroe sensible technique"

I think the whole thing needs a rewrite.

The points should be that browser detection is:
1) unreliable (can't trust navigator.userAgent)
2) uses an unrelated inference (it is unrelated to the problem it is
trying to solve), which:
a. causes forwards-compatibility problems
b. hides the reasoning behind the workaround, which makes
understanding the thinking behind the code more difficult to understand.

Though I haven't drafted anything. Still working on the notes index page.

Garrett
 
Reply With Quote
 
 
 
 
Dr J R Stockton
Guest
Posts: n/a
 
      06-01-2009
In comp.lang.javascript message <gvvtr2$4nd$(E-Mail Removed)-
september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
<(E-Mail Removed)> posted:
>
> if (document.getElementById &&
> document.getElementById('el') &&
> document.getElementById('el').style ) {
> // We know that this browser supports getElementById and has
> // a style object, so we can set a style property.
> document.getElementById('el').style.color = "red";
> }


Although understandable, that looks inefficient. The following, after
checking, can be presented for actual use.


if (document.getElementById &&
(T=document.getElementById('Divn')) && (T=T.style) ) {
// ...
// ...
T.color = "red";
}

In IE, but not Firefox, one can start with

if ((T=document.getElementById) && (T=T('Divn'))


--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 7.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
I find MiniTrue useful for viewing/searching/altering files, at a DOS prompt;
free, DOS/Win/UNIX, <URL:http://www.idiotsdelight.net/minitrue/> unsupported.
 
Reply With Quote
 
 
 
 
David Mark
Guest
Posts: n/a
 
      06-01-2009
On Jun 1, 4:24*pm, Dr J R Stockton <(E-Mail Removed)>
wrote:
> In comp.lang.javascript message <gvvtr2$(E-Mail Removed)-
> september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
> <(E-Mail Removed)> posted:
>
>
>
> > *if (document.getElementById &&
> > * * *document.getElementById('el') &&
> > * * *document.getElementById('el').style ) {
> > * *// We know that this browser supports getElementById and has
> > * *// a style object, so we can set a style property.
> > * *document.getElementById('el').style.color = "red";
> > *}

>
> Although understandable, that looks inefficient. *The following, after
> checking, can be presented for actual use.
>
> * if (document.getElementById &&
> * * * (T=document.getElementById('Divn')) && (T=T.style) ) {
> * * * // ...
> * * * // ...
> * * * * T.color = "red";
> * }


What is with the uppercase identifiers? They only serve to confuse
the casual reader. I don't like assignments in conditionals either.

And you *never* test host methods by type conversion. Use the typeof
operator or search the archive for isHostMethod (or areHostMethods.)

>
> In IE, but not Firefox, one can start with
>
> * if ((T=document.getElementById) && (T=T('Divn'))


That's a worthless aside, but somebody is bound to copy it without the
disclaimer.
 
Reply With Quote
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      06-02-2009
Dr J R Stockton <(E-Mail Removed)> writes:

> In comp.lang.javascript message <gvvtr2$4nd$(E-Mail Removed)-
> september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
> <(E-Mail Removed)> posted:
>>
>> if (document.getElementById &&
>> document.getElementById('el') &&
>> document.getElementById('el').style ) {
>> // We know that this browser supports getElementById and has
>> // a style object, so we can set a style property.
>> document.getElementById('el').style.color = "red";
>> }

>
> Although understandable, that looks inefficient.


Being understandable is more important than being efficient 90% of the
time (or more). That said, repeated subexpressions like in the above make
give me twitches.

> The following, after
> checking, can be presented for actual use.
>
> if (document.getElementById &&
> (T=document.getElementById('Divn')) && (T=T.style) ) {
> // ...
> // ...
> T.color = "red";
> }


Remember to declare T as a variable, i.e., preceed the above by
"var T".

Personally I would prefer to check for document.getElementById only
once, but if this code is executed only once, that wouldn't be
relevant.

And assignments (any side effect, really) inside conditional expressions
is not very readable. It should be avoided where possible.

For one-shot code I would write it as:

if (document.getElemenetById) { // or use typeof for extra safety
var elem = document.getElementById('el');
if (elem && elem.style) { // why test for style if getElementById
// exists. I don't believe there is any
// browser that has getElementById and
// not element.style.
elem.style.color = "red";
}
}


/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

 
Reply With Quote
 
Garrett Smith
Guest
Posts: n/a
 
      06-02-2009
Lasse Reichstein Nielsen wrote:
> Dr J R Stockton <(E-Mail Removed)> writes:
>
>> In comp.lang.javascript message <gvvtr2$4nd$(E-Mail Removed)-
>> september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
>> <(E-Mail Removed)> posted:
>>> if (document.getElementById &&
>>> document.getElementById('el') &&
>>> document.getElementById('el').style ) {
>>> // We know that this browser supports getElementById and has
>>> // a style object, so we can set a style property.
>>> document.getElementById('el').style.color = "red";
>>> }

>> Although understandable, that looks inefficient.

>
> Being understandable is more important than being efficient 90% of the
> time (or more). That said, repeated subexpressions like in the above make
> give me twitches.
>


[mental image of LRN twitching...]

Oh no, lets chagne that right away!

Kidding, of course

[...]

>
> For one-shot code I would write it as:
>
> if (document.getElemenetById) { // or use typeof for extra safety
> var elem = document.getElementById('el');
> if (elem && elem.style) { // why test for style if getElementById
> // exists. I don't believe there is any
> // browser that has getElementById and
> // not element.style.
> elem.style.color = "red";
> }
> }
>


Cumbersome to have that inline, though. I would not want to have that
much code every time I wanted to set a style.

Regarding the code comment, I don't know. Browsers that have a
scriptable document but do not have document.getElementById?

Is there a browser that does not have a userAgent string?

A draft with a totally different example below. I threw in "host
object", which is not in the glossary (glossary does not exist).

Anyone want to write a glossary? Start out with a list terms. They'll
get defined by members here. That can be added to the FAQ, or can be an
"appendix".

================================================== ====================
8.6 _How do I detect Opera/Netscape/IE_?

Short answer: Don't do that.

The navigator host object contains properties that may identify
the browser and version. These properties are historically inaccurate.
Some browsers allow the user to set navigator.userAgent to any value.
For example, Firefox, (type about:config and search useragent
or Safari, Develop > User Agent > Other..., IE, via Registry.

Other browsers, such as Opera, provide a list of user agents
for the user to select from. There are also at least 25 other
javascript capable browsers, with multiple versions, each
with their own string.

Browser detection is unreliable, at best. It usually causes
forwards-compatibility and maintenance problems. It is unrelated
to the problem or incompatiblity it is trying to solve, and tends
obscures the thinking behind the code.

Object detection is checking that the object in question exists.
Capability detection goes one step further to actually test the
objects, methods, or properties, to see if it behaves in the
desired manner.


/**
* Returns the element/object the user targeted.
* If neither DOM nor IE event model is supported, returns undefined.
* @throws TypeError if the event is not an object.
*/
function getEventTarget(e) {
e = e || window.event;
// First check for the existence of standard "target" property.
if("target" in e) {
return e.target;
}
return e.srcElement;
}

See also:
<URL: http://jibbering.com/faq/faq_notes/n...er_detect.html >
<URL: http://dev.opera.com/articles/view/u...ity-detection/ >
<URL: http://developer.apple.com/internet/...detection.html >
<URL: http://www.w3.org/Protocols/rfc2616/....html#sec14.43 >

================================================== ====================
Garrett

--
The official comp.lang.javascript FAQ:
http://jibbering.com/faq/
 
Reply With Quote
 
Dr J R Stockton
Guest
Posts: n/a
 
      06-02-2009

I use, sometimes, multi-dimensional sparse arrays; if one needs to
determine whether A[i][j][k] exists, or to read it safely, IIRC it is
necessary to check (possibly) whether A exists, then whether A[i]
exists, then whether A[i][j] exists, then whether A[i][j][k] exists.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      06-02-2009
Garrett Smith wrote:
> Lasse Reichstein Nielsen wrote:
>> For one-shot code I would write it as:
>>
>> if (document.getElemenetById) { // or use typeof for extra safety


And lose one `e'

>> var elem = document.getElementById('el');
>> if (elem && elem.style) { // why test for style if getElementById
>> // exists. I don't believe there is any
>> // browser that has getElementById and
>> // not element.style.
>> elem.style.color = "red";
>> }
>> }
>>

>
> Cumbersome to have that inline, though. I would not want to have that
> much code every time I wanted to set a style.


See dhtml.setStyleProperty(). That's one call in source code (of course, it
spawns a few more). The efficient software developer writes (or at least
attempts to write) efficient wrappers for everyday tasks.

> Regarding the code comment, I don't know. Browsers that have a
> scriptable document but do not have document.getElementById?


Entirely possible, see IE < 5.

> Is there a browser that does not have a userAgent string?


Depends on what you are asking. There is probably no *browser* that does
not have navigator.userAgent, as object and property originate from
JavaScript 1.0, Netscape 2.0. However, a) there are UAs that are not
browsers which support ECMAScript scripting, and b) the property value is
implementation-dependent, of course.

Why are you asking?

> Anyone want to write a glossary?


A glossary of what?

> /**
> * Returns the element/object the user targeted.
> * If neither DOM nor IE event model is supported, returns undefined.
> * @throws TypeError if the event is not an object.
> */
> function getEventTarget(e) {
> e = e || window.event;
> // First check for the existence of standard "target" property.
> if("target" in e) {


It is quite pointless to use a feature that is not supported in previous
versions of a programming language or API to determine if features
introduced in previous versions of a programming language or API are
supported. Besides, the `in' operation should not be used with host objects
in particular.

> return e.target;
> }
> return e.srcElement;


What for? var t = e.target || e.srcElement; Couldn't be simpler.


PointedEars
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      06-02-2009
On Jun 2, 3:13*pm, Thomas 'PointedEars' Lahn <(E-Mail Removed)>
wrote:
> Garrett Smith wrote:
> > Lasse Reichstein Nielsen wrote:
> >> For one-shot code I would write it as:

>
> >> *if (document.getElemenetById) { // or use typeof for extra safety

>
> And lose one `e'
>
> >> * *var elem = document.getElementById('el');
> >> * *if (elem && elem.style) { // why test for style if getElementById
> >> * * * * * * * * * * * * * * *// exists. I don't believe there is any
> >> * * * * * * * * * * * * * * *// browser that has getElementById and
> >> * * * * * * * * * * * * * * *// not element.style.
> >> * * *elem.style.color = "red";
> >> * *}
> >> *}

>
> > Cumbersome to have that inline, though. I would not want to have that
> > much code every time I wanted to set a style.

>
> See dhtml.setStyleProperty(). *That's one call in source code (of course, it
> spawns a few more). *The efficient software developer writes (or at least
> attempts to write) efficient wrappers for everyday tasks.
>
> > Regarding the code comment, I don't know. Browsers that have a
> > scriptable document but do not have document.getElementById?

>
> Entirely possible, see IE < 5.


Obviously.

>
> > Is there a browser that does not have a userAgent string?

>
> Depends on what you are asking. *There is probably no *browser* that does
> not have navigator.userAgent, as object and property originate from
> JavaScript 1.0, Netscape 2.0. *However, a) there are UAs that are not
> browsers which support ECMAScript scripting, and b) the property value is
> implementation-dependent, of course.
>
> Why are you asking?
>
> > Anyone want to write a glossary?

>
> A glossary of what?
>
> > /**
> > * * Returns the element/object the user targeted.
> > * * If neither DOM nor IE event model is supported, returns undefined..
> > * * @throws TypeError if the event is not an object.
> > * */
> > function getEventTarget(e) {
> > * *e = e || window.event;
> > * *// First check for the existence of standard "target" property.
> > * *if("target" in e) {

>
> It is quite pointless to use a feature that is not supported in previous
> versions of a programming language or API to determine if features
> introduced in previous versions of a programming language or API are
> supported. *Besides, the `in' operation should not be used with host objects
> in particular.


Exactly. I'm a bit tired of this revisionist approach to feature
testing. We've settled these issues and nothing like this is going in
the FAQ if I have anything to say about it (and you know I will.)

>
> > * * *return e.target;
> > * *}
> > * *return e.srcElement;

>
> What for? *var t = e.target || e.srcElement; *Couldn't be simpler.


Exactly.
 
Reply With Quote
 
Garrett Smith
Guest
Posts: n/a
 
      06-02-2009
David Mark wrote:
> On Jun 2, 3:13 pm, Thomas 'PointedEars' Lahn <(E-Mail Removed)>
> wrote:
>> Garrett Smith wrote:
>>> Lasse Reichstein Nielsen wrote:


[...]

>>> return e.target;
>>> }
>>> return e.srcElement;

>> What for? var t = e.target || e.srcElement; Couldn't be simpler.

>
> Exactly.


Agreed.

--
The official comp.lang.javascript FAQ:
http://jibbering.com/faq/
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      06-02-2009
On Jun 2, 3:49*pm, Conrad Lender <(E-Mail Removed)> wrote:
> On 02/06/09 21:24, David Mark wrote:
>
> > On Jun 2, 3:13 pm, Thomas 'PointedEars' Lahn <(E-Mail Removed)>
> > wrote:
> >> Garrett Smith wrote:
> >>> Anyone want to write a glossary?

>
> >> A glossary of what?

>
> ...of terms which are frequently used in this group but may be new to
> beginners. "Host object", "DontEnum", "[[term-from-the-specs]]", and
> abbreviations like UA come to mind, for example.
>
> >> Besides, the `in' operation should not be
> >> used with host objects in particular.

>
> > Exactly. *I'm a bit tired of this revisionist approach to feature
> > testing. *We've settled these issues [..]

>
> Hm. The in operator doesn't give a lot of information in this context


Correct. It tells you virtually nothing.

> (ok, so "foo" is in document, but is it what we were looking for?), but
> apart from that it should be relatively safe - ie, should not cause a


No, it is perfectly ridiculous to use the - in - operator for feature
detection as there are agents that do not support it. Think about
what feature detection is used for.

> crash. There was one specific exception to this, but I can't remember
> what exactly. Some problem in Safari, I think.


Not that I know of. Of course, I virtually never use the - in -
operator.

>
> >>> * return e.target;
> >>> }
> >>> return e.srcElement;

>
> >> What for? *var t = e.target || e.srcElement; *Couldn't be simpler.

>
> > Exactly.

>
> Except that this won't always evaluate to an element.


That's allowable and must be dealt with accordingly after the target
has been determined.

> IIRC, there was an
> issue with Safari where it would let events fire on text nodes. In that
> case you'd have to check the nodeType of 't' and use its parentNode if
> necessary.


It is neither an issue, nor Safari-specific. This is one of the first
things I fixed (by proxy) in jQuery way back when. And what is a
nodeType of 't' supposed to be?
 
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
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
FAQ Topic - How do I detect Opera/Safari/IE? (2012-02-19) FAQ server Javascript 0 02-19-2012 12:00 AM
FAQ or not FAQ? =?ISO-8859-15?Q?Juli=E1n?= Albo C++ 28 01-15-2007 04:33 AM
FAQ Topic - How do I detect Opera/Netscape/IE? FAQ server Javascript 19 09-10-2006 07:53 PM
[de] Update of FAQ in German/FAQ auf Deutsch ueberarbeitet Josef 'Jupp' Schugt Ruby 0 09-22-2003 08:56 PM



Advertisments