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

Discussion in 'Javascript' started by Garrett Smith, Jun 1, 2009.

  1. 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/doc...Developing_Cross_Browser/Cross_Platform_Pages
    >

    <URL: http://jibbering.com/faq/faq_notes/not_browser_detect.html >
    <URL: http://dev.opera.com/articles/view/using-capability-detection/ >
    <URL:
    http://developer.apple.com/internet/webcontent/objectdetection.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
     
    Garrett Smith, Jun 1, 2009
    #1
    1. Advertising

  2. In comp.lang.javascript message <gvvtr2$4nd$-
    september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
    <> 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.
     
    Dr J R Stockton, Jun 1, 2009
    #2
    1. Advertising

  3. Garrett Smith

    David Mark Guest

    On Jun 1, 4:24 pm, Dr J R Stockton <>
    wrote:
    > In comp.lang.javascript message <gvvtr2$-
    > september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
    > <> 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.
     
    David Mark, Jun 2, 2009
    #3
  4. Dr J R Stockton <> writes:

    > In comp.lang.javascript message <gvvtr2$4nd$-
    > september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
    > <> 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'
     
    Lasse Reichstein Nielsen, Jun 2, 2009
    #4
  5. Lasse Reichstein Nielsen wrote:
    > Dr J R Stockton <> writes:
    >
    >> In comp.lang.javascript message <gvvtr2$4nd$-
    >> september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
    >> <> 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/not_browser_detect.html >
    <URL: http://dev.opera.com/articles/view/using-capability-detection/ >
    <URL: http://developer.apple.com/internet/webcontent/objectdetection.html >
    <URL: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 >

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

    --
    The official comp.lang.javascript FAQ:
    http://jibbering.com/faq/
     
    Garrett Smith, Jun 2, 2009
    #5
  6. I use, sometimes, multi-dimensional sparse arrays; if one needs to
    determine whether A[j][k] exists, or to read it safely, IIRC it is
    necessary to check (possibly) whether A exists, then whether A
    exists, then whether A[j] exists, then whether A[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)
     
    Dr J R Stockton, Jun 2, 2009
    #6
  7. 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
     
    Thomas 'PointedEars' Lahn, Jun 2, 2009
    #7
  8. Garrett Smith

    David Mark Guest

    On Jun 2, 3:13 pm, Thomas 'PointedEars' Lahn <>
    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.
     
    David Mark, Jun 2, 2009
    #8
  9. David Mark wrote:
    > On Jun 2, 3:13 pm, Thomas 'PointedEars' Lahn <>
    > 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/
     
    Garrett Smith, Jun 2, 2009
    #9
  10. Garrett Smith

    David Mark Guest

    On Jun 2, 3:49 pm, Conrad Lender <> wrote:
    > On 02/06/09 21:24, David Mark wrote:
    >
    > > On Jun 2, 3:13 pm, Thomas 'PointedEars' Lahn <>
    > > 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?
     
    David Mark, Jun 2, 2009
    #10
  11. Thomas 'PointedEars' Lahn wrote:
    > Garrett Smith wrote:
    >> Lasse Reichstein Nielsen wrote:


    [...]

    >> 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?
    >


    It would be a novel find.

    >> Anyone want to write a glossary?

    >
    > A glossary of what?
    >


    The glossary would contain terms that get used and sometimes need
    clarification or reiteration.

    Terms like:
    "Host Object"
    "Script Engine"
    "Layout Engine"
    "Quirks Mode"
    "Primitive value"
    "Object inference"
    "Scope"

    Ideally they would have short definitions, too.

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

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


    It could lose the identifier |t|.

    return e.target || e.srcElement;

    Garrett
    --
    The official comp.lang.javascript FAQ:
    http://jibbering.com/faq/
     
    Garrett Smith, Jun 2, 2009
    #11
  12. Conrad Lender wrote:
    > On 02/06/09 21:55, David Mark wrote:
    >> On Jun 2, 3:49 pm, Conrad Lender <> wrote:
    >>> 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.

    >
    > As always, it depends on the requirements. If it's important that any
    > and all UAs are able to execute the scripts without syntax errors, then
    > 'in' is not an option (and neither are try..catch).
    >
    >>> 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.

    >
    > Ah, I got that mixed up: I found the thread again, and the crash only
    > happened with 'typeof', but could be avoided with 'in'. Possibly just an
    > interesting anomaly, but it demonstrates that not even 'typeof' is
    > always safe.
    >
    > http://preview.tinyurl.com/p7aocu (starting with message #126)
    >
    >>>>> 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?

    >
    > Usually element (1), or text (3) if the browser decides it wants to fire
    > events on text nodes, too. What else?
    >
    >


    Or 9 if document.

    Or undefined if the object is not a Node, such as window.

    Garrett

    --
    The official comp.lang.javascript FAQ:
    http://jibbering.com/faq/
     
    Garrett Smith, Jun 2, 2009
    #12
  13. kangax wrote:
    > Conrad Lender wrote:
    > [...]
    >> crash. There was one specific exception to this, but I can't remember
    >> what exactly. Some problem in Safari, I think.

    >
    > Any of Safari 2.x., to be precise.
    >
    > I posted a testcase which exhibits the crash
    > <http://groups.google.com/group/comp.lang.javascript/msg/7a7ddde62e65b80b>
    > and I think Garrett confirmed that bug on his machine.
    >


    I did. Here:
    http://groups.google.com/group/comp.lang.javascript/msg/1e34a215461e10da
    and here:
    http://groups.google.com/group/comp.lang.javascript/msg/7127bbeac65dd8c2

    > Nevertheless, as David pointed out, you wouldn't really fiddle with `in`
    > or `typeof`. Those should really be abstracted in
    > `isHostMethod`/`areHostMethods` (used to determine client capabilities
    > *before* initializing certain app behavior) instead of cluttering the code.
    >


    An extra method call.

    As for "clutter":-

    isHostMethod(obj, prop)
    vs.
    (prop in obj)

    The former is more and would be slower. isHostMethod is a bad name. It
    would seem to indicate that the property is host method. That is not
    what it does.

    isPossibleHostMethod()

    would be a more accurate name. Still though, AISB, isHostMethod doesn't
    really tell you much about the value of an arbitrary host object.

    Garrett
    --
    The official comp.lang.javascript FAQ:
    http://jibbering.com/faq/
     
    Garrett Smith, Jun 2, 2009
    #13
  14. David Mark wrote:
    > On Jun 2, 3:49 pm, Conrad Lender <> wrote:
    >> On 02/06/09 21:24, David Mark wrote:
    >>
    >>> On Jun 2, 3:13 pm, Thomas 'PointedEars' Lahn <>
    >>> wrote:
    >>>> Garrett Smith wrote:
    >>>>> Anyo


    [...]

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


    The beauty of it is that you don't even have to deal with it in most cases.

    Most times, you just want to know if the target matches certain
    criteria, like:-

    hasClass(target, "scroll-actuator").

    A text node or the document should not have a className property. Even
    if it did, the return value of that |hasClass| call above would still be
    false (unless the odd program intentionally set a className property on
    that object, but that would be a fault of the program).

    >> 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?


    Which recent browsers still include text nodes? Gecko did that for a
    long while but stopped at some point.

    Garrett
    --
    The official comp.lang.javascript FAQ:
    http://jibbering.com/faq/
     
    Garrett Smith, Jun 3, 2009
    #14
  15. Garrett Smith

    David Mark Guest

    On Jun 2, 6:40 pm, Garrett Smith <> wrote:
    > kangax wrote:
    > > Conrad Lender wrote:
    > > [...]
    > >> crash. There was one specific exception to this, but I can't remember
    > >> what exactly. Some problem in Safari, I think.

    >
    > > Any of Safari 2.x., to be precise.

    >
    > > I posted a testcase which exhibits the crash
    > > <http://groups.google.com/group/comp.lang.javascript/msg/7a7ddde62e65b80b>
    > > and I think Garrett confirmed that bug on his machine.

    >
    > I did. Here:http://groups.google.com/group/comp.lang.javascript/msg/1e34a215461e10da
    > and here:http://groups.google.com/group/comp.lang.javascript/msg/7127bbeac65dd8c2
    >
    > > Nevertheless, as David pointed out, you wouldn't really fiddle with `in`
    > > or `typeof`. Those should really be abstracted in
    > > `isHostMethod`/`areHostMethods` (used to determine client capabilities
    > > *before* initializing certain app behavior) instead of cluttering the code.

    >
    > An extra method call.


    Doesn't matter for these. And what happens when some new version of
    IE comes out and starts throwing exceptions on using the - in -
    operator with - for example - element nodes (similar things have
    happened before.) You've got to go back and change every one of
    them. So I don't see a wrapper-less solution as workable.

    >
    > As for "clutter":-
    >
    > isHostMethod(obj, prop)
    > vs.
    > (prop in obj)


    I think he's alluding to the fact that these are called once in a
    gateway (usually during or on load), not sprinkled throughout the
    code. You can also use areHostMethods. Much easier on the eyes. No
    compatibility issues at all. I can't see a better solution. I've
    been sold ever since 2001 (approx.) when it fixed the most mysterious
    Mac IE bug I'd ever seen. Sure enough, it was an "unknown" type.
    Then I heard a few years back that nobody could detect the bookmark
    methods in IE. Once again, an "unknown" type. Gecko's document.all
    is an "undefined" type, despite its availability (clearly a cue from
    the Gecko developers to stay away from it.) If you listen, the
    browser developers are giving hints and the - typeof - operator is
    what reveals them to your script.

    >
    > The former is more and would be slower. isHostMethod is a bad name. It
    > would seem to indicate that the property is host method. That is not
    > what it does.
    >
    > isPossibleHostMethod()


    Rubbish. It's the perfect name. It should always be documented to
    remind the author to pass names of known methods, not any random
    property name. If it passes - for example - gEBI, you can be quite
    sure it is a host method. Other scripts overwriting (or adding) gEBI
    don't count (throw those away.)

    >
    > would be a more accurate name. Still though, AISB, isHostMethod doesn't
    > really tell you much about the value of an arbitrary host object.


    Certainly it does. Over a decade of history confirms it and that is
    all you have to go on in this case. It is the - in - operator that
    tells you nothing. You are focusing on semantics, not reality and
    your interpretation is wrong anyway. You are not supposed to pass an
    *arbitrary* anything. The rules for these methods (there are three or
    four) have been very clearly defined and each serves a very specific
    purpose.
     
    David Mark, Jun 3, 2009
    #15
  16. David Mark wrote:
    > On Jun 2, 6:40 pm, Garrett Smith <> wrote:
    >> kangax wrote:
    >>> Conrad Lender wrote:
    >>> [...]
    >>>> crash. There was one specific exception to this, but I can't remember
    >>>> what exactly. Some problem in Safari, I think.
    >>> Any of Safari 2.x., to be precise.
    >>> I posted a testcase which exhibits the crash
    >>> <http://groups.google.com/group/comp.lang.javascript/msg/7a7ddde62e65b80b>
    >>> and I think Garrett confirmed that bug on his machine.

    >> I did. Here:http://groups.google.com/group/comp.lang.javascript/msg/1e34a215461e10da
    >> and here:http://groups.google.com/group/comp.lang.javascript/msg/7127bbeac65dd8c2
    >>
    >>> Nevertheless, as David pointed out, you wouldn't really fiddle with `in`
    >>> or `typeof`. Those should really be abstracted in
    >>> `isHostMethod`/`areHostMethods` (used to determine client capabilities
    >>> *before* initializing certain app behavior) instead of cluttering the code.

    >> An extra method call.

    >
    > Doesn't matter for these. And what happens when some new version of
    > IE comes out and starts throwing exceptions on using the - in -
    > operator with - for example - element nodes (similar things have
    > happened before.) You've got to go back and change every one of
    > them. So I don't see a wrapper-less solution as workable.
    >


    Sounds like FUD.

    A wrapperless solution involves using |in| where |in| works and typeof
    where it doesn't.

    A wrapper could do that, too, or could use combinations of the two
    operators (using |in| as a guard clause to prevent the Safari 2 crash
    kangax mentioned).

    >> As for "clutter":-
    >>
    >> isHostMethod(obj, prop)
    >> vs.
    >> (prop in obj)

    >
    > I think he's alluding to the fact that these are called once in a
    > gateway (usually during or on load), not sprinkled throughout the
    > code. You can also use areHostMethods. Much easier on the eyes. No
    > compatibility issues at all. I can't see a better solution. I've
    > been sold ever since 2001 (approx.) when it fixed the most mysterious
    > Mac IE bug I'd ever seen. Sure enough, it was an "unknown" type.


    I'm can't prove it was not, but I bet you are wrong on that.

    > Then I heard a few years back that nobody could detect the bookmark
    > methods in IE. Once again, an "unknown" type. Gecko's document.all
    > is an "undefined" type, despite its availability (clearly a cue from
    > the Gecko developers to stay away from it.) If you listen, the
    > browser developers are giving hints and the - typeof - operator is
    > what reveals them to your script.


    The reason |typeof document.all| is "undefined" is not because Gecko's
    developers are saying to stay away from it. The reason is so that
    existing scripts that check document.all can continue to function the same.

    Do you really need |typeof| to tell you not to use document.all?

    >
    >> The former is more and would be slower. isHostMethod is a bad name. It
    >> would seem to indicate that the property is host method. That is not
    >> what it does.
    >>
    >> isPossibleHostMethod()

    >
    > Rubbish.


    Huh.

    It's the perfect name. It should always be documented to
    > remind the author to pass names of known methods, not any random
    > property name. If it passes - for example - gEBI, you can be quite
    > sure it is a host method. Other scripts overwriting (or adding) gEBI
    > don't count (throw those away.)
    >


    isHostMethod(document, "getElementById");

    >> would be a more accurate name. Still though, AISB, isHostMethod doesn't
    >> really tell you much about the value of an arbitrary host object.

    >
    > Certainly it does. Over a decade of history confirms it and that is
    > all you have to go on in this case. It is the - in - operator that
    > tells you nothing. You are focusing on semantics, not reality and
    > your interpretation is wrong anyway. You are not supposed to pass an
    > *arbitrary* anything. The rules for these methods (there are three or
    > four) have been very clearly defined and each serves a very specific
    > purpose.


    What you've stated in the above paragraph (the one I am directly
    replying to) is that isHostMethod requires the developer to have a
    presupposition about what the presence of an object property means about it.

    So, IIUC, isHostMethod detects the presence of a property, and that it
    is not a primitive value (it even has to call [[Get]] to do that). Did I
    get that right?

    Does isHostMethod tell you if the object is a host object? Nope. It does
    not tell you if the property is a callable object (method), either.

    I will wait another day before I upload the FAQ, to allow for more
    feedback. One thing at a time. The "format a date" question needs
    attention now, so that is waiting for this.

    Garrett
    --
    The official comp.lang.javascript FAQ:
    http://jibbering.com/faq/
     
    Garrett Smith, Jun 3, 2009
    #16
  17. Garrett Smith

    Matt Kruse Guest

    On Jun 2, 2:13 pm, Thomas 'PointedEars' Lahn <>
    wrote:
    > >    if("target" in e) {
    > >      return e.target;
    > >    }
    > >    return e.srcElement;

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


    These don't have exactly the same meaning, of course.

    I don't know that the condition actually exists in reality, but if
    e.target is ever null, your alternative will return undefined instead
    of null.

    Matt Kruse
     
    Matt Kruse, Jun 3, 2009
    #17
  18. Matt Kruse wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >>> if("target" in e) {
    >>> return e.target;
    >>> }
    >>> return e.srcElement;

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

    >
    > These don't have exactly the same meaning, of course.


    Yes, they have. In addition, the W3C DOM has e.relatedTarget, and the
    MSHTML DOM has e.fromElement and e.toElement.

    > I don't know that the condition actually exists in reality, but if
    > e.target is ever null,


    It can't be.

    > your alternative will return undefined instead of null.


    Correct, but irrelevant because

    if (t)

    covers both.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Jun 3, 2009
    #18
  19. Garrett Smith wrote:
    > Conrad Lender wrote:
    >> On 02/06/09 21:55, David Mark wrote:
    >>> On Jun 2, 3:49 pm, Conrad Lender <> wrote:
    >>>> 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?

    >> Usually element (1), or text (3) if the browser decides it wants to
    >> fire events on text nodes, too. What else?

    >
    > Or 9 if document.
    >
    > Or undefined if the object is not a Node, such as window.


    <http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247>


    PointedEars
     
    Thomas 'PointedEars' Lahn, Jun 3, 2009
    #19
  20. Garrett Smith

    David Mark Guest

    On Jun 3, 1:05 am, Garrett Smith <> wrote:
    > David Mark wrote:
    > > On Jun 2, 6:40 pm, Garrett Smith <> wrote:
    > >> kangax wrote:
    > >>> Conrad Lender wrote:
    > >>> [...]
    > >>>> crash. There was one specific exception to this, but I can't remember
    > >>>> what exactly. Some problem in Safari, I think.
    > >>> Any of Safari 2.x., to be precise.
    > >>> I posted a testcase which exhibits the crash
    > >>> <http://groups.google.com/group/comp.lang.javascript/msg/7a7ddde62e65b80b>
    > >>> and I think Garrett confirmed that bug on his machine.
    > >> I did. Here:http://groups.google.com/group/comp.lang.javascript/msg/1e34a215461e10da
    > >> and here:http://groups.google.com/group/comp.lang.javascript/msg/7127bbeac65dd8c2

    >
    > >>> Nevertheless, as David pointed out, you wouldn't really fiddle with `in`
    > >>> or `typeof`. Those should really be abstracted in
    > >>> `isHostMethod`/`areHostMethods` (used to determine client capabilities
    > >>> *before* initializing certain app behavior) instead of cluttering thecode.
    > >> An extra method call.

    >
    > > Doesn't matter for these.  And what happens when some new version of
    > > IE comes out and starts throwing exceptions on using the - in -
    > > operator with - for example - element nodes (similar things have
    > > happened before.)  You've got to go back and change every one of
    > > them.  So I don't see a wrapper-less solution as workable.

    >
    > Sounds like FUD.
    >
    > A wrapperless solution involves using |in| where |in| works and typeof
    > where it doesn't.
    >
    > A wrapper could do that, too, or could use combinations of the two
    > operators (using |in| as a guard clause to prevent the Safari 2 crash
    > kangax mentioned).
    >
    > >> As for "clutter":-

    >
    > >> isHostMethod(obj, prop)
    > >> vs.
    > >> (prop in obj)

    >
    > > I think he's alluding to the fact that these are called once in a
    > > gateway (usually during or on load), not sprinkled throughout the
    > > code.  You can also use areHostMethods.  Much easier on the eyes.  No
    > > compatibility issues at all.  I can't see a better solution.  I've
    > > been sold ever since 2001 (approx.) when it fixed the most mysterious
    > > Mac IE bug I'd ever seen.  Sure enough, it was an "unknown" type.

    >
    > I'm can't prove it was not, but I bet you are wrong on that.


    Are you kidding? It was an "unknown" type. That's a fact. And it
    behaved just as the "unknown" types do in Windows (blows up on type
    conversion, among other things.)

    >
    > > Then I heard a few years back that nobody could detect the bookmark
    > > methods in IE.  Once again, an "unknown" type.  Gecko's document.all
    > > is an "undefined" type, despite its availability (clearly a cue from
    > > the Gecko developers to stay away from it.)  If you listen, the
    > > browser developers are giving hints and the - typeof - operator is
    > > what reveals them to your script.

    >
    > The reason |typeof document.all| is "undefined" is not because Gecko's
    > developers are saying to stay away from it. The reason is so that
    > existing scripts that check document.all can continue to function the same.


    That is exactly what I said. I didn't say a thing about Gecko's
    developers trying to stay away from it.

    >
    > Do you really need |typeof| to tell you not to use document.all?


    I don't know what that means.

    >
    >
    >
    > >> The former is more and would be slower. isHostMethod is a bad name. It
    > >> would seem to indicate that the property is host method. That is not
    > >> what it does.

    >
    > >> isPossibleHostMethod()

    >
    > > Rubbish.  

    >
    > Huh.


    As in refuse.

    >
    > It's the perfect name.  It should always be documented to
    >
    > > remind the author to pass names of known methods, not any random
    > > property name.  If it passes - for example - gEBI, you can be quite
    > > sure it is a host method.  Other scripts overwriting (or adding) gEBI
    > > don't count (throw those away.)

    >
    > isHostMethod(document, "getElementById");


    And?

    >
    > >> would be a more accurate name. Still though, AISB, isHostMethod doesn't
    > >> really tell you much about the value of an arbitrary host object.

    >
    > > Certainly it does.  Over a decade of history confirms it and that is
    > > all you have to go on in this case.  It is the - in - operator that
    > > tells you nothing.  You are focusing on semantics, not reality and
    > > your interpretation is wrong anyway.  You are not supposed to pass an
    > > *arbitrary* anything.  The rules for these methods (there are three or
    > > four) have been very clearly defined and each serves a very specific
    > > purpose.

    >
    > What you've stated in the above paragraph (the one I am directly
    > replying to) is that isHostMethod requires the developer to have a
    > presupposition about what the presence of an object property means about it.


    YES. We've discussed this to death. The first argument is a host
    object. Not an Object object or a string or whatever. The second is
    the name of a method. Not a name of any other type of property. I
    think it is quite clear. The name kind of says it all.

    >
    > So, IIUC, isHostMethod detects the presence of a property, and that it
    > is not a primitive value (it even has to call [[Get]] to do that). Did I
    > get that right?


    Not even in the ballpark. And I don't think you are really trying.

    >
    > Does isHostMethod tell you if the object is a host object? Nope.


    That is not what it does. In fact, such a method would be completely
    idiotic (see jQuery.) And see above.

    > It does
    > not tell you if the property is a callable object (method), either.


    Oh, but it does. Perhaps not in the way you would like, but it is the
    only way in reality.

    >
    > I will wait another day before I upload the FAQ, to allow for more
    > feedback. One thing at a time. The "format a date" question needs
    > attention now, so that is waiting for this.


    I don't care what you do with that thing.
     
    David Mark, Jun 3, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Davisro
    Replies:
    3
    Views:
    406
    bruce barker
    Apr 29, 2004
  2. Joe Price
    Replies:
    6
    Views:
    648
    Joe Price
    Sep 26, 2003
  3. Bob
    Replies:
    24
    Views:
    1,546
  4. FAQ server
    Replies:
    19
    Views:
    217
    Richard Cornford
    Sep 10, 2006
  5. FAQ server
    Replies:
    0
    Views:
    1,241
    FAQ server
    Feb 19, 2012
Loading...

Share This Page