getElementsByTagName

Discussion in 'Javascript' started by Michel Bany, Jul 7, 2005.

  1. Michel Bany

    Michel Bany Guest

    I am trying to parse responseXML from an HTTP request.
    var doc = request.responseXML;
    var elements = doc.getElementsByTagName("*");
    the last statement returns an empty collection when running from IE6.
    It returns the expected collection when running under Firefox or Mozilla.
    Anybody can explain ?
    Michel.
    Michel Bany, Jul 7, 2005
    #1
    1. Advertising

  2. Michel Bany

    knocte Guest

    Michel Bany escribió:
    > I am trying to parse responseXML from an HTTP request.
    > var doc = request.responseXML;
    > var elements = doc.getElementsByTagName("*");
    > the last statement returns an empty collection when running from IE6.
    > It returns the expected collection when running under Firefox or Mozilla.
    > Anybody can explain ?
    > Michel.


    I think that the function getElementsByTagName does not accept the
    string "*" in IE. You will have to correct the DOM behaviour of IE with
    something like this:

    function IsIE(){
    return window.document.all?true:false;
    }

    if (IsIE()) {
    function getElementsByTagName_IE(sTag){
    if ((!sTag)||(sTag=='')||(sTag=='*')){
    return window.document.all;
    }

    return document.all.tags(sTag);
    }
    window.document.getElementsByTagName = getElementsByTagName_IE;
    }

    Regards,

    knocte

    --
    knocte, Jul 8, 2005
    #2
    1. Advertising

  3. Michel Bany

    Jim Ley Guest

    On Fri, 08 Jul 2005 01:27:54 +0200, knocte
    <> wrote:

    >function IsIE(){
    > return window.document.all?true:false;
    >}


    this is not a remotely acceptable way of detecting if the behaviour of
    getElementsByTagName("*") returns what you want it to, document.all is
    supported by a very large number of user agents, and is certainly not
    a discriminator for IE!

    if (document.getElementsByTagName) {
    var els=document.getElementsByTagName("*");
    if (els.length==0) {
    // do whatever...
    }
    }


    Jim.
    Jim Ley, Jul 8, 2005
    #3
  4. Michel Bany

    RobG Guest

    Michel Bany wrote:
    > I am trying to parse responseXML from an HTTP request.
    > var doc = request.responseXML;
    > var elements = doc.getElementsByTagName("*");
    > the last statement returns an empty collection when running from IE6.
    > It returns the expected collection when running under Firefox or Mozilla.
    > Anybody can explain ?
    > Michel.


    Something like the following should do the trick:

    function getEmAll() {
    var els;
    if ( document.getElementsByTagName ) {
    els = document.getElementsByTagName('*');
    }
    if ( ( !els || !els.length ) && document.all ) {
    els = document.all;
    }
    return els;
    }

    Note you should check the returned value, there is still plenty of scope
    for failure.

    --
    Rob
    RobG, Jul 8, 2005
    #4
  5. Michel Bany <> wrote in message news:42cd9eb6$0$1254$...
    > I am trying to parse responseXML from an HTTP request.
    > var doc = request.responseXML;
    > var elements = doc.getElementsByTagName("*");
    > the last statement returns an empty collection when running from IE6.
    > It returns the expected collection when running under Firefox or Mozilla.
    > Anybody can explain ?
    > Michel.


    I get around this by giving priority to document.all if it is available. This will support I.E. but may not work for
    some DOM browsers that do not support document.all or the getElementsByTagName wildcard.

    var allElements=document.all || document.getElementsByTagName("*");

    if(typeof allElements != 'undefined' && allElements.length)
    ...

    This page http://www.siteexperts.com/tips/contents/ts16/page3.asp shows a recursive function that accesses all
    elements. Modifying it to append to a supplied array, I found that it returns one element less than
    document.getElementsByTagName("*"), probably the html element.


    function getElements(allElems, obj)
    {
    for (var i=0;i < obj.childNodes.length;i++)
    if (obj.childNodes.nodeType==1) // Elements only


    allElems[allElems.length]=obj.childNodes;
    getElements(allElems,obj.childNodes)
    }
    }

    var allElements=[];
    getElements( allElements, document.childNodes[0])


    --
    Stephen Chalmers
    547265617375726520627572696564206174204F2E532E207265663A205451323437393134
    Stephen Chalmers, Jul 8, 2005
    #5
  6. Michel Bany

    ASM Guest

    Jim Ley wrote:
    >
    > if (document.getElementsByTagName) {
    > var els=document.getElementsByTagName("*");
    > if (els.length==0) {
    > // do whatever...
    > }
    > }


    hello Jim,

    IE is not reactive with this ccs rule :
    td { color: blue }
    td:hover { color: red }

    if(document.all) being digested by others browsers than IE
    which detection have I to place in my code in this case ?


    --
    Stephane Moriaux et son [moins] vieux Mac
    ASM, Jul 8, 2005
    #6
  7. Michel Bany wrote:

    > I am trying to parse responseXML from an HTTP request.
    > var doc = request.responseXML;
    > var elements = doc.getElementsByTagName("*");
    > the last statement returns an empty collection when running from IE6.


    The wild card '*' is supported when I test here with MSXML 3 on Windows
    XP and IE 6, I am not sure about earlier MSXML releases without testing.

    Are you sure the XML is properly loaded and parsed when
    getElementsByTagName("*") gives you an empty collection?


    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Jul 8, 2005
    #7
  8. On 08/07/2005 07:28, ASM wrote:

    [snip]

    > IE is not reactive with this ccs rule :
    > td { color: blue }
    > td:hover { color: red }


    IE is deficient and doesn't recognise the hover pseudo-class on any
    elements except A.

    > if(document.all) being digested by others browsers than IE
    > which detection have I to place in my code in this case ?


    You don't perform any detection at all, at least in the sense of looking
    for IE. What you're looking for is specific behaviour, and then an
    alternative method of achieving what you want.

    var collection;

    /* If gEBTN is supported, attempt to use it. */
    if(document.getElementsByTagName) {
    collection = document.getElementsByTagName('*');
    }

    /* If the previous attempt failed... */
    if(!collection || !collection.length) {

    /* Check to see if we can use the all property
    * to obtain a collection of all elements in
    * the document.
    *
    * Note that this is *not* a check for IE, but
    * a feature test.
    */
    if(document.all) {
    collection = document.all;

    /* If not, return an empty array as failure. */
    } else {
    collection = [];
    }
    }


    More self-contained (but much more complex):

    var getByTagName = (function() {
    function isGenericObject(value) {
    return isObject(value) || ('function' == typeof value);
    }
    function isObject(value) {
    return !!value && ('object' == typeof value);
    }
    function tryDOM(a, tN) {
    var e = useDOM(a, tN);

    if('*' == tN) {
    if(e.length) {
    this.getByTagName = useDOM;
    } else {
    e = useTags(a, tN);
    if(e.length) {this.getByTagName = useTags;}
    }
    }
    return e;
    }
    function useDOM(a, tN) {
    return a.getElementsByTagName(tN);
    }
    function useEmpty() {return [];}
    function useTags(a, tN) {
    return ('*' == tN) ? a.all : a.all.tags(tN);
    }
    return function(a, tN) {
    this.getByTagName = isGenericObject(a.getElementsByTagName)
    ? isObject(a.all) && isObject(a.all.tags)
    ? tryDOM
    : useDOM
    : isObject(a.all) && isObject(a.all.tags)
    ? useTags
    : useEmpty;

    return this.getByTagName(a, tN);
    };
    })();

    What you'd use depends on whether you'd end up repeating code. The above
    really boils down to something quite simple and efficient, though it may
    not look like it at first glance.

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
    Michael Winter, Jul 8, 2005
    #8
  9. Michel Bany

    ASM Guest

    Re: Detect IE [was] getElementsByTagName

    Michael Winter wrote:
    >
    > IE is deficient and doesn't recognise the hover pseudo-class on any
    > elements except A.


    Yes, it's what I said (or approx)
    and it is exactly what I want to detect.

    >> if(document.all) being digested by others browsers than IE
    >> which detection have I to place in my code in this case ?

    >
    >
    > You don't perform any detection at all, at least in the sense of looking
    > for IE. What you're looking for is specific behaviour, and then an
    > alternative method of achieving what you want.
    >
    > var collection;
    >
    > /* If gEBTN is supported, attempt to use it. */
    > if(document.getElementsByTagName) {
    > collection = document.getElementsByTagName('*');
    > }


    Does IE Windows unsupport this collection ?

    I want to detect IE and IE only
    Or much better :
    I want to detect browsers
    which don't recognise pseudo-class (eventualy except on tag A)

    >
    > /* If the previous attempt failed... */
    > if(!collection || !collection.length) {
    >
    > /* Check to see if we can use the all property
    > * to obtain a collection of all elements in
    > * the document.
    > *
    > * Note that this is *not* a check for IE, but
    > * a feature test.
    > */
    > if(document.all) {
    > collection = document.all;
    >
    > /* If not, return an empty array as failure. */
    > } else {
    > collection = [];
    > }
    > }


    I think that test is quite egal if(document.all)
    and doesn't permit to say : there is IE and IE only

    > More self-contained (but much more complex):


    so complex that I understand anything
    does that do what I want ?

    > var getByTagName = (function() {
    > function isGenericObject(value) {
    > return isObject(value) || ('function' == typeof value);
    > }
    > function isObject(value) {
    > return !!value && ('object' == typeof value);
    > }
    > function tryDOM(a, tN) {
    > var e = useDOM(a, tN);
    > if('*' == tN) {
    > if(e.length) {
    > this.getByTagName = useDOM;
    > }
    > else {
    > e = useTags(a, tN);
    > if(e.length) {this.getByTagName = useTags;}
    > }
    > }
    > return e;
    > }
    > function useDOM(a, tN) {
    > return a.getElementsByTagName(tN);
    > }
    > function useEmpty() {return [];}
    > function useTags(a, tN) {
    > return ('*' == tN) ? a.all : a.all.tags(tN);
    > }
    > return function(a, tN) {
    > this.getByTagName = isGenericObject(a.getElementsByTagName)
    > ? isObject(a.all) && isObject(a.all.tags)
    > ? tryDOM
    > : useDOM
    > : isObject(a.all) && isObject(a.all.tags)
    > ? useTags
    > : useEmpty;
    >
    > return this.getByTagName(a, tN);
    > };
    > })();


    As I understood anything, does this getByTagName return false if
    pseudo-class not allowed for tags TD ?



    --
    Stephane Moriaux et son [moins] vieux Mac
    ASM, Jul 9, 2005
    #9
  10. Re: Detect IE [was] getElementsByTagName

    On 09/07/2005 00:58, ASM wrote:

    > Michael Winter wrote:
    >
    >> IE is deficient and doesn't recognise the hover pseudo-class on any
    >> elements except A.

    >
    > Yes, it's what I said (or approx)


    Your comment was, to me, so random and at a tangent to the current topic
    that I read it as a question, rather than a statement.

    > and it is exactly what I want to detect.


    That's the first time you've said as much.

    [snip]

    >> var collection;
    >>
    >> /* If gEBTN is supported, attempt to use it. */
    >> if(document.getElementsByTagName) {
    >> collection = document.getElementsByTagName('*');
    >> }

    >
    > Does IE Windows unsupport this collection ?


    Again, I'm confused as to what you mean. Perhaps: "Will IE/Win ever
    return a non-empty collection using this code?" If so, then yes, IE6
    will return a collection containing all elements within the document, as
    it should. IE5.x will always return an empty collection, and IE4 doesn't
    support the getElementsByTagName method at all.

    > I want to detect IE and IE only


    Browser detection is flawed, and has been since browsers first started
    trying to spoof other browsers. However, you can use Microsoft's
    conditional comments mechanism which is, as far as I know, only
    implemented by IE.

    > Or much better :
    > I want to detect browsers
    > which don't recognise pseudo-class (eventualy except on tag A)


    You can't do that.

    [snipped getElementsByTagName emulation]

    > As I understood anything, does this getByTagName return false if
    > pseudo-class not allowed for tags TD ?


    You've only just explained your desire to detect the lack of support for
    the :hover pseudo-class, so of course that code doesn't do what you
    want. It accomplished what I read as the direction of discussion: how to
    handle earlier IE versions which didn't support the getElementsByTagName
    method properly.


    You cannot detect what is supported in CSS via scripting. However, what
    you can do is emulate some of that functionality. If you want to alter
    the appearance of an element, then implement it in both CSS and script:

    td {
    background-color: transparent;
    color: blue;
    }

    td.on-hover,
    td:hover {
    background-color: transparent;
    color: red;
    }


    <td onmouseover="this.className='on-hover';"
    onmouseout="this.className='';">...</td>

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
    Michael Winter, Jul 9, 2005
    #10
  11. Michel Bany

    Michel Bany Guest


    >This page http://www.siteexperts.com/tips/contents/ts16/page3.asp shows a recursive function that accesses all
    >elements. Modifying it to append to a supplied array, I found that it returns one element less than
    >document.getElementsByTagName("*"), probably the html element.
    >
    >
    >function getElements(allElems, obj)
    >{
    > for (var i=0;i < obj.childNodes.length;i++)
    > if (obj.childNodes.nodeType==1) // Elements only
    >
    >
    > allElems[allElems.length]=obj.childNodes;
    > getElements(allElems,obj.childNodes)
    > }
    >}
    >
    >var allElements=[];
    >getElements( allElements, document.childNodes[0])
    >
    >
    >

    This recursive function works superbly with Firefox and Mozilla, but not
    with IE6,
    var request = new ActiveXObject("Microsoft.XMLHTTP");
    <.. build and send the request ..>
    var nodes = request.responseXML.childNodes[0];
    I am getting an empty collection for nodes. What's wrong ?
    Michel.
    Michel Bany, Jul 9, 2005
    #11
  12. Michel Bany

    ASM Guest

    Re: Detect IE [was] getElementsByTagName

    Michael Winter wrote:

    sory to have turned of a file from its original question
    as mine would be seen as an extension ( ?)

    thanks for your patience and answer

    > On 09/07/2005 00:58, ASM wrote:
    >
    >> I want to detect browsers
    >> which don't recognise pseudo-class (eventualy except on tag A)

    >
    > You can't do that.


    [snip]


    > You cannot detect what is supported in CSS via scripting. However, what
    > you can do is emulate some of that functionality. If you want to alter
    > the appearance of an element, then implement it in both CSS and script:
    >
    > td {
    > background-color: transparent;
    > color: blue;
    > }
    >
    > td.on-hover,
    > td:hover {
    > background-color: transparent;
    > color: red;
    > }
    >
    >
    > <td onmouseover="this.className='on-hover';"
    > onmouseout="this.className='';">...</td>


    because I wouln't want charge css compatible browsers with events they
    don't need (and aso not to much poluate html code)
    and because I have double class (and theire hovers) on same element
    (depend if selected or not)
    by that my wanted is some more complex than a simple roll-over
    I'd made a JS code attibutting at page loaded this events only if IE

    exercices (tables rows or cells selections)
    examples are (in french) here :
    http://perso.wanadoo.fr/stephane.moriaux/truc/tables_highlight_rows_fr.htm
    more complex :
    http://perso.wanadoo.fr/stephane.moriaux/truc/tables_highlight_cells_fr.htm
    to compare with same for only css (and few JS)
    http://perso.wanadoo.fr/stephane.moriaux/truc/tables_highlight_cells_css.htm

    all of them based on an ie dectection (mixed with iCab)
    detection ignoring capabilities of other unknown browsers

    --
    Stephane Moriaux et son [moins] vieux Mac
    ASM, Jul 9, 2005
    #12
  13. Michel Bany wrote:


    > var request = new ActiveXObject("Microsoft.XMLHTTP");
    > <.. build and send the request ..>
    > var nodes = request.responseXML.childNodes[0];
    > I am getting an empty collection for nodes. What's wrong ?



    Hard to tell, check
    request.status
    request.statusText
    request.getAllResponseHEaders()
    then check
    request.responseXML.parseError.errorCode
    request.responseXML.parseError.reason
    for IE, that should allow to tell what happens.



    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Jul 9, 2005
    #13
  14. Michel Bany

    VK Guest

    > I am trying to parse responseXML from an HTTP request.
    > var doc = request.responseXML;
    > var elements = doc.getElementsByTagName("*");


    responseXML doesn't work this way in IE. Overall it's a bogus method:
    doesn't fail on calling it, but always gives you empty string for any
    XML methods. If you *really* have a valid XML data from your server,
    you have to use XML parser first:

    ....
    if (window.XMLHttpRequest) {
    // FF & Co
    }
    else {
    try {
    var myDataIsland = new ActiveXObject("Msxml3.DOMDocum­ent");}
    catch (e1) {
    var myDataIsland = new ActiveXObject("Msxml2.DOMDocum­ent");}
    }
    if (myDataIsland != null) {
    var myInOutStream = new ActiveXObject("Microsoft.XMLHT­TP");
    <pseudo-code - read data using myInOutStream>
    <pseudo-code - if success>
    myDataIsland.loadXML(myInOutSt­ream.responseText);
    }
    }

    >From this point forward myDataIsland contains perfectly formatted and

    parsed XML data.

    Now you can: var elm = myDataIsland.getElementsByTagName("*");
    It works perfectly in IE.

    All the above has sense only if you are really getting a valid XML from
    your server. If it's just an unstructured set of strings you're calling
    XML for convenience, then simply read your text and parse it manually
    in the way you want:
    var txt = myInOutSt­ream.responseText;
    ....

    responseText method always works no matter what.
    VK, Jul 11, 2005
    #14
  15. Michel Bany

    ASM Guest

    VK wrote:
    >>I am trying to parse responseXML from an HTTP request.
    >>var doc = request.responseXML;
    >>var elements = doc.getElementsByTagName("*");

    >
    >
    > responseXML doesn't work this way in IE. Overall it's a bogus method:
    > doesn't fail on calling it, but always gives you empty string for any
    > XML methods. If you *really* have a valid XML data from your server,
    > you have to use XML parser first:
    >
    > ...
    > if (window.XMLHttpRequest) {
    > // FF & Co
    > }
    > else {


    if(document.all && navigator.userAgent.indexOf('Mac')<0)

    > try {


    try is not understood by my NC 4.5 and gives an error

    > var myDataIsland = new ActiveXObject("Msxml3.DOMDocum­ent");}
    > catch (e1) {
    > var myDataIsland = new ActiveXObject("Msxml2.DOMDocum­ent");}
    > }
    > if (myDataIsland != null) {
    > var myInOutStream = new ActiveXObject("Microsoft.XMLHT­TP");
    > <pseudo-code - read data using myInOutStream>
    > <pseudo-code - if success>
    > myDataIsland.loadXML(myInOutSt­ream.responseText);
    > }
    > }
    >
    >>From this point forward myDataIsland contains perfectly formatted and

    > parsed XML data.
    >
    > Now you can: var elm = myDataIsland.getElementsByTagName("*");
    > It works perfectly in IE.
    >
    > All the above has sense only if you are really getting a valid XML from
    > your server. If it's just an unstructured set of strings you're calling
    > XML for convenience, then simply read your text and parse it manually
    > in the way you want:
    > var txt = myInOutSt­ream.responseText;
    > ...
    >
    > responseText method always works no matter what.
    >



    --
    Stephane Moriaux et son [moins] vieux Mac
    ASM, Jul 11, 2005
    #15
  16. Michel Bany

    VK Guest

    > try is not understood by my NC 4.5 and gives an error

    With all my respect to the old glory of Netscape, NN 4.5 is out of the
    scope of support as of the year 2005 (as well as IE 3.02, NN3 Gold,
    NCSA Mozaic and others). If for some reasons you want to stay with NN4,
    I suggest you at least upgrade to NN 4.71 (that was the last
    cummulative upgrade for NN4). NN 4.5 was one of the most bugs-full in
    the series.
    VK, Jul 11, 2005
    #16
  17. Michel Bany

    ASM Guest

    VK wrote:
    >>try is not understood by my NC 4.5 and gives an error

    >
    > With all my respect to the old glory of Netscape, NN 4.5


    :)

    On my old Mac, NC4.5 is (exept IE 5.1 (is it really a browser?))
    the alone acceptable
    You can also use Mozilla 1.02 (US) if you accept its 2 mn for loading
    (and 20 seconds on each new popup)

    Then, there are some countries where people are happy to can use
    very old UC ... (without ADSL or DSL) and by the fact old browsers.

    --
    Stephane Moriaux et son [moins] vieux Mac
    ASM, Jul 11, 2005
    #17
  18. Michel Bany

    VK Guest

    > On my old Mac, NC4.5 is the alone acceptable

    And what's wrong with Opera?
    <http://www.opera.com/download/?platform=mac>

    Has its faults, but pretty stable, lightweight, and at least you can
    work with modern DOM/scripting.


    > IE 5.1 (is it really a browser?))

    It is, and a good one. Just don't tell it to anyone! :-X
    VK, Jul 11, 2005
    #18
  19. Michel Bany

    ASM Guest

    VK wrote:
    >>On my old Mac, NC4.5 is the alone acceptable

    >
    >
    > And what's wrong with Opera?


    Opera 6.03 is a daube (buggued to the bone)

    > <http://www.opera.com/download/?platform=mac>


    donwloaded just now
    version 8 seems to run correctly on my new mac
    I'll can be more friend with him (not to much cause pub)



    --
    Stephane Moriaux et son [moins] vieux Mac
    ASM, Jul 11, 2005
    #19
  20. VK wrote:

    >>I am trying to parse responseXML from an HTTP request.
    >>var doc = request.responseXML;
    >>var elements = doc.getElementsByTagName("*");

    >
    >
    > responseXML doesn't work this way in IE. Overall it's a bogus method:
    > doesn't fail on calling it, but always gives you empty string for any
    > XML methods.


    responseXML is not a method but a property and it is not part of the IE
    object model but of the MSXML (Microsoft's XML parser) object model. And
    of course if the HTTP response is served as text/xml or application/xml
    then MSXML tries to parse the response body and populates responseXML as
    an XML DOM document if the markup is well-formed. No need to reparse
    responseText.



    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Jul 11, 2005
    #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. =?Utf-8?B?Sm9l?=

    SelectNodes vs. GetElementsByTagName

    =?Utf-8?B?Sm9l?=, Nov 2, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    41,117
    =?Utf-8?B?Sm9l?=
    Nov 2, 2005
  2. mynamehere
    Replies:
    0
    Views:
    438
    mynamehere
    Dec 14, 2003
  3. Danny
    Replies:
    1
    Views:
    410
    wooks
    Jul 23, 2004
  4. Ragnar Heil
    Replies:
    5
    Views:
    7,507
    Ragnar Heil
    Apr 27, 2005
  5. Simon Dahlbacka

    xml getElementsByTagName w/o recursion?

    Simon Dahlbacka, Feb 11, 2004, in forum: Python
    Replies:
    2
    Views:
    1,201
    Chris Herborth
    Feb 11, 2004
Loading...

Share This Page