Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #28428 > unrolled thread

Recursive function to find a node in the DOM

Started by"danca (Daniele Campagna)" <cyberdanny@tiscalinet.it>
First post2015-07-15 09:59 +0200
Last post2015-08-06 10:20 +0200
Articles 20 on this page of 30 — 5 participants

Back to article view | Back to comp.lang.javascript


Contents

  Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-07-15 09:59 +0200
    Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-15 11:59 +0200
      Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-15 12:03 +0200
      Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-07-15 13:36 +0200
        Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-19 12:27 +0200
          Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-19 12:34 +0200
          Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-07-21 12:08 +0200
            Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-25 14:11 +0200
              Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-07-25 21:22 +0200
                Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-27 16:12 +0200
      Re: Recursive function to find a node in the DOM "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-08-08 04:50 +0200
        Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-08-08 09:33 +0200
          Re: Recursive function to find a node in the DOM "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-08-12 00:48 +0200
            Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-08-12 01:18 +0200
              Re: Recursive function to find a node in the DOM "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-08-13 23:26 +0200
                Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-08-16 08:48 +0200
                  Re: Recursive function to find a node in the DOM "Christoph M. Becker" <cmbecker69@arcor.de> - 2015-08-20 02:11 +0200
    Re: Recursive function to find a node in the DOM Scott Sauyet <scott.sauyet@gmail.com> - 2015-07-18 15:59 -0700
      Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-07-21 12:30 +0200
        Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-21 13:53 +0200
          Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-07-21 14:51 +0200
            Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-07-21 16:05 +0200
              Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-07-21 20:35 +0200
              Re: Recursive function to find a node in the DOM Scott Sauyet <scott.sauyet@gmail.com> - 2015-07-30 22:10 -0700
                Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-08-06 10:07 +0200
                  Re: Recursive function to find a node in the DOM Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-08-06 20:15 +0200
                    Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-08-08 01:21 +0200
          Re: Recursive function to find a node in the DOM Scott Sauyet <scott.sauyet@gmail.com> - 2015-07-30 22:09 -0700
    Re: Recursive function to find a node in the DOM Denis McMahon <denismfmcmahon@gmail.com> - 2015-07-29 03:04 +0000
      Re: Recursive function to find a node in the DOM "danca (Daniele Campagna)" <cyberdanny@tiscalinet.it> - 2015-08-06 10:20 +0200

Page 1 of 2  [1] 2  Next page →


#28428 — Recursive function to find a node in the DOM

From"danca (Daniele Campagna)" <cyberdanny@tiscalinet.it>
Date2015-07-15 09:59 +0200
SubjectRecursive function to find a node in the DOM
Message-ID<mo53os$am9$1@dont-email.me>
I wrote this small recursive function to find a node (having a name) in 
a DOM element:

//usage: nodeFind (element to inspect (object), f.e. a form, name of the 
element to search for, 3rd parameter empty at first call)

function nodeFind(el,n,retval){
  if (el.name==n) {
  	return (el)
  }else{
  	if (el.hasChildNodes) {
		for (var z=0;z<el.childNodes.length;++z){
			var a=el.childNodes.item(z);
			retval=nodeFind(a,n,retval)
		}
	 }
  }
  return retval
//^^^^^^^^^^^^ note!
}

I needed to find a specific control in a form, in order to substitute an 
<input readonly> with a <file> (via replaceChild()) to upload a file if 
the form is prevalidated, etc.
(then IIRC I discovered that IE was not able to refer to the substitued 
control via <form>[name] - this is another story :-) )

I put it in public domain if ever some newbies finds it useful, and 
obviously to discuss with "big chops" here if this is robust enough to 
be considered cross-browser and definitive.

I am using it from long time and it seems to work well on every browser.
One strange thing is the way recursion is implemented in javascript: I 
did not put the "return retval" statement at first, it seems unuseful, 
and went crazy before discovering that it is needed.

Dan
-- 
"Everybody should pay taxes with a smile"
I tried, but they want money.

[toc] | [next] | [standalone]


#28433

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-15 11:59 +0200
Message-ID<5530725.v0RXNFEj4j@PointedEars.de>
In reply to#28428
danca (Daniele Campagna) wrote:

> I wrote this small recursive function to find a node (having a name) in
> a DOM element:
> 
> //usage: nodeFind (element to inspect (object), f.e. a form, name of the
> element to search for, 3rd parameter empty at first call)
> 
> function nodeFind(el,n,retval){
>   if (el.name==n) {
>   return (el)
>   }else{
>   if (el.hasChildNodes) {
> for (var z=0;z<el.childNodes.length;++z){
> var a=el.childNodes.item(z);
> retval=nodeFind(a,n,retval)
> }
> }
>   }
>   return retval
> //^^^^^^^^^^^^ note!
> }

document.forms[…].elements[…] and getElementsByTagName(…) exist.  You do not 
need that function even for Netscape Navigator 2 (the fact aside that it 
would not work there as it is).
 
> I needed to find a specific control in a form, in order to substitute an
> <input readonly> with a <file> (via replaceChild()) to upload a file if
> the form is prevalidated, etc.
> (then IIRC I discovered that IE was not able to refer to the substitued
> control via <form>[name] - this is another story :-) )

If you can change the input[type="text"] into an input[type="file"], for 
security reasons the value of the control will be reset, and you cannot set 
the “value” property of an input[type="file"] for the same reason.  So this 
appears to be a futile exercise (other than to test the security fix).
 
> I am using it from long time and it seems to work well on every browser.

… that you know about and have tested.

> One strange thing is the way recursion is implemented in javascript: I
> did not put the "return retval" statement at first, it seems unuseful,
> and went crazy before discovering that it is needed.

There is no “javascript”.  Of course you need a break condition to prevent 
infinite recursion; this has nothing to do with what you think would be 
“javascript”.  And the proper approach here is iteration (walking the 
document tree), not recursion; because the stack size and/or nesting level 
is limited (the Google Groups archive has test results), but an element’s 
nesting level within a document tree is not.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28434

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-15 12:03 +0200
Message-ID<1862910.GjkSvAaOTz@PointedEars.de>
In reply to#28433
Thomas 'PointedEars' Lahn wrote:

> danca (Daniele Campagna) wrote:
>> I wrote this small recursive function to find a node (having a name) in
>> a DOM element:
>> 
>> //usage: nodeFind (element to inspect (object), f.e. a form, name of the
>> element to search for, 3rd parameter empty at first call)
>> 
>> function nodeFind(el,n,retval){
>>   if (el.name==n) {
>>   return (el)
>>   }else{

Unnecessary “else” block.  (You *really* want to start using a decent IDE 
with semantic validation.)

>> […]
>> }
> 
> document.forms[…].elements[…] and getElementsByTagName(…) exist.

I mean getElementsByName(…), of course.

> You do not need that function even for Netscape Navigator 2 (the fact 
> aside that it would not work there as it is).

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28437

From"danca (Daniele Campagna)" <cyberdanny@tiscalinet.it>
Date2015-07-15 13:36 +0200
Message-ID<mo5gf4$l2m$1@dont-email.me>
In reply to#28433
Il 07/15/2015 11:59 AM, Thomas 'PointedEars' Lahn ha scritto:
>
> document.forms[…].elements[…] and getElementsByTagName(…) exist.  You do not
> need that function even for Netscape Navigator 2 (the fact aside that it
> would not work there as it is).
>

The idea was to have a very generalized function. It finds whatever 
<name> in whatever <container>, and is used in a series of web 
applications I wrote, so I'm not tied to a tagName nor I use it only for 
forms...

>
> If you can change the input[type="text"] into an input[type="file"], for
> security reasons the value of the control will be reset, and you cannot set
> the “value” property of an input[type="file"] for the same reason.  So this
> appears to be a futile exercise (other than to test the security fix).

I know of that. But it is not an exercise. The scenario here is: a user 
can post a message in a [kinda of] message system. Messages can have 
attachments. If the author wants to edit the message he posted, he may 
want to change the text or the attachment. So he has a button "change 
attachment", and the input showing the name of the actual attachment 
becomes a <file> to select another one and upload it. :-)

>
>> One strange thing is the way recursion is implemented in javascript: I
>> did not put the "return retval" statement at first, it seems unuseful,
>> and went crazy before discovering that it is needed.
>
> There is no “javascript”.

ECMA, ok, ECMA.

Of course you need a break condition to prevent
> infinite recursion; this has nothing to do with what you think would be
> “javascript”.

Well I only wanted to point out that in other languages (f.e. xbase, the 
main language I use - to write CGI's at present -) I would have written 
the very same function with no need to put a return statement there.

And the proper approach here is iteration (walking the
> document tree), not recursion; because the stack size and/or nesting level
> is limited (the Google Groups archive has test results), but an element’s
> nesting level within a document tree is not.
>

Yes, but all this stuff is server-side generated, so I am quite in 
control of the pages (they are small in size) and I must confess that I 
like very much the recursive approach - but I am aware of the stack 
growth and memory consumption it causes.

Dan
-- 
"Everybody should pay taxes with a smile"
I tried, but they want money.

[toc] | [prev] | [next] | [standalone]


#28453

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-19 12:27 +0200
Message-ID<4029225.tIX9iqhVEp@PointedEars.de>
In reply to#28437
danca (Daniele Campagna) wrote:

> Il 07/15/2015 11:59 AM, Thomas 'PointedEars' Lahn ha scritto:
>> document.forms[…].elements[…] and getElementsByTagName(…) exist.  You do
>> not need that function even for Netscape Navigator 2 (the fact aside that
>> it would not work there as it is).
> 
> The idea was to have a very generalized function. It finds whatever
> <name> in whatever <container>, and is used in a series of web
> applications I wrote, so I'm not tied to a tagName nor I use it only for
> forms...

See my correction.  You can use the getElementsByName(…) method for that; it 
is available on HTML document objects in implementations of W3C DOM Level 2 
HTML (since 2003) and HTML5.

The getElementsByName(…) method is not available on element objects (at 
least not in a standards-compliant way; implementations may vary); however, 
the getElementsByTagName(…) method is, starting from IE/MSHTML 5.5 at the 
latest.  That method can be called as element.getElementsByTagName("*"), and 
the resulting NodeList can be filtered, if you do not want to be tied to a 
specific “tagName” property value.  If all else fails, the return value of 
document.getElementsByTagName("*") can be filtered.

Higher Levels of the W3C DOM, implemented in recent Web layout engines, 
support other such methods that are more flexible, too: 
document.evaluate(…) for XPath queries, and document.querySelector(…) and 
document.querySelectorAll() for CSS queries.


Also, you are reinventing the wheel.  Several common libraries provide such 
a function, by using a query engine or otherwise.  So I do not foresee many 
people being interested in your function.

That said, I do not see why you would need this algorithm that finds an 
element by name in any context in the first place because there are more 
efficient built-in ones.  The “name” attribute is only allowed for the 
following element types (cf. [1] and [2]):

  - “a” elements:

    It is more efficient to filter “document.links” or the return value of
    node.getElementsByTagName("a").  Where “document.links” is not only a
    NodeList but a HTMLCollection, document.links["…"] is the most efficient
    approach.

    Also, the “name” attribute is obsolete for “a” elements since HTML5, in
    favor of the “id” attribute which allows those “a” elements to be
    referred by the return value of document.getElementById(…).

  - “applet” elements:

    It is more efficient to filter document.applets or the return value of 
    node.getElementsByTagName("applet").  Also, the “applet” element is
    deprecated in HTML 4, and obsolete since HTML5.

  - “form” elements:

    It is more efficient to use document.forms["…"].

  - form controls:

    There should not be form controls in an HTML document that are not part
    of a form.  Only an ancestor “form” element guarantees proper validation
    in HTML 5, and that this event works without client-side scripting
    everywhere.  Controls of a specific form can be referred to by name
    with document.forms[…].elements["…"].

    In most cases it is not even necessary to refer to the form by name 
    or index because form controls have a “form” property to refer to the
    form they are a part of, and “this” can be used in event-handler
    attributes and event listeners to refer to the element object for the
    element that fired the event.

    However, in case a form control is not part of a form, 
    document.getElementsByName("…"), document.getElementById("…"), or
    node.getElementsByTagName("…") suffice.  Because the same name SHOULD
    NOT be used for different kinds of element types, such as both for an
    “object” element and a form control.

  - “frame” and “iframe” elements:

    It is more efficient to use window.frames["…"].

  - “img” elements

    It is more efficient to use document.images["…"].  Also, the “name”
    attribute is obsolete for “img” elements since HTML5.

  - “map” elements:

    It is more efficient to filter the return value of 
    node.getElementsByTagName("map").

  - “meta” elements:

    It is more efficient to filter the return value of 
    node.getElementsByTagName("meta") or, because the “name” attribute
    of META elements has historically been of the NAME type, there would
    not be more than one element with that name in the document, and
    document.getElementsByName("…") can be used.

  - “object” elements:

    It is more efficient to filter document.applets or the return value of
    node.getElementsByTagName("object").

    <http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-85113862>

  - “param” elements:

    It is more efficient to filter the return value of
    node.getElementsByTagName("param").

[1] <http://www.w3.org/TR/1999/REC-html401-19991224/index/attributes.html>
[2] <http://www.w3.org/TR/2014/REC-html5-20141028//index.html#attributes-1>

>> If you can change the input[type="text"] into an input[type="file"], for
>> security reasons the value of the control will be reset, and you cannot
>> set the “value” property of an input[type="file"] for the same reason.  
>> So this appears to be a futile exercise (other than to test the security
>> fix).
> 
> I know of that. But it is not an exercise. The scenario here is: a user
> can post a message in a [kinda of] message system. Messages can have
> attachments. If the author wants to edit the message he posted, he may
> want to change the text or the attachment. So he has a button "change
> attachment", and the input showing the name of the actual attachment
> becomes a <file> to select another one and upload it. :-)

(“Exercise” was not to be understood verbatim.)  See my correction.  There 
appears to be no point to use a read-only input[type="text"] element here if 
you want to support IE/MSHTML because you need to replace the element in any 
case.

>>> One strange thing is the way recursion is implemented in javascript: I
>>> did not put the "return retval" statement at first, it seems unuseful,
>>> and went crazy before discovering that it is needed.
>>
>> There is no “javascript”.
> 
> ECMA, ok, ECMA.

There is no ECMA (anymore).  There are Ecma International, and the 
ECMAScript Language Specification (named for historical reasons).  But what 
matters more than the name is the fact that this specification has several 
*different* implementations; several of them have “JavaScript” in their 
name.

> Of course you need a break condition to prevent infinite recursion; this 
> has nothing to do with what you think would be “javascript”.
> 
> Well I only wanted to point out that in other languages (f.e. xbase, the
> main language I use - to write CGI's at present -) I would have written
> the very same function with no need to put a return statement there.

I do not know xbase.  ECMAScript is a language of the C family, so you need 
to return a value from a function if you want to avoid an implicit return 
value.  The implicit return value is the “undefined” value in ECMAScript 
implementations.
 
> And the proper approach here is iteration (walking the
>> document tree), not recursion; because the stack size and/or nesting
>> level is limited (the Google Groups archive has test results), but an
>> element’s nesting level within a document tree is not.
> 
> Yes, but all this stuff is server-side generated, so I am quite in
> control of the pages (they are small in size) and I must confess that I
> like very much the recursive approach - but I am aware of the stack
> growth and memory consumption it causes.

Above you have claimed generality for this function, and you have expressed 
desire to make it available to the public because of that.  It fails to do 
that job if it does not work with any document.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28454

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-19 12:34 +0200
Message-ID<1636165.RvOSKfTF1j@PointedEars.de>
In reply to#28453
Thomas 'PointedEars' Lahn wrote:

> […]  You can use the getElementsByName(…) method for that;
> it is available on HTML document objects in implementations of W3C DOM
> Level 2 HTML (since 2003) and HTML5.
> 
> The getElementsByName(…) method is not available on element objects (at
> least not in a standards-compliant way; implementations may vary);
> however, the getElementsByTagName(…) method is, starting from IE/MSHTML
> 5.5 at the latest.  That method can be called as 
> element.getElementsByTagName("*"), and the resulting NodeList can be
> filtered, if you do not want to be tied to a specific “tagName” property
> value.  If all else fails, the return value of 
> document.getElementsByTagName("*") can be filtered.

[References that were accidentally cut from the draft: ]

<https://html.spec.whatwg.org/multipage/dom.html#dom-tree-accessors:dom-document-getelementsbyname>

<http://www.w3.org/TR/dom/#dom-element-getelementsbytagname>

> Higher Levels of the W3C DOM, implemented in recent Web layout engines,
> support other such methods that are more flexible, too:
> document.evaluate(…) for XPath queries, and document.querySelector(…) and
> document.querySelectorAll() for CSS queries.

<http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator-evaluate>

<http://www.w3.org/TR/2013/REC-selectors-api-20130221/#interface-definitions>
 
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28456

From"danca (Daniele Campagna)" <cyberdanny@tiscalinet.it>
Date2015-07-21 12:08 +0200
Message-ID<mol5k8$v99$1@dont-email.me>
In reply to#28453
Il 07/19/2015 12:27 PM, Thomas 'PointedEars' Lahn ha scritto:

>
> See my correction.  You can use the getElementsByName(…) method for that; it
> is available on HTML document objects in implementations of W3C DOM Level 2
> HTML (since 2003) and HTML5.
>
> The getElementsByName(…) method is not available on element objects (at
> least not in a standards-compliant way; implementations may vary); however,
> the getElementsByTagName(…) method is, starting from IE/MSHTML 5.5 at the
> latest.  That method can be called as element.getElementsByTagName("*"), and
> the resulting NodeList can be filtered, if you do not want to be tied to a
> specific “tagName” property value.  If all else fails, the return value of
> document.getElementsByTagName("*") can be filtered.
>
> Higher Levels of the W3C DOM, implemented in recent Web layout engines,
> support other such methods that are more flexible, too:
> document.evaluate(…) for XPath queries, and document.querySelector(…) and
> document.querySelectorAll() for CSS queries.
>
>
> Also, you are reinventing the wheel.  Several common libraries provide such
> a function, by using a query engine or otherwise.  So I do not foresee many
> people being interested in your function.

OK, but I don't use any for now (apart the possibility I offer to have 
the photo gallery managed via jQuery + fancybox - if one absolutely 
wants that nice animation effect and is fine with the 100+ Kb of overhead).

>
> That said, I do not see why you would need this algorithm that finds an
> element by name in any context in the first place because there are more
> efficient built-in ones.  The “name” attribute is only allowed for the
> following element types (cf. [1] and [2]):
>
>    - “a” elements:
...
Many thanks, this is a very useful summary (and I will add it to my 
fragments of documentation i collect here and there). Very clear. But 
IIUC, I would need different functions for different elements, and maybe 
feature testing for getElementsByName...

>
>    - form controls:
>
>      There should not be form controls in an HTML document that are not part
>      of a form.  Only an ancestor “form” element guarantees proper validation
>      in HTML 5, and that this event works without client-side scripting
>      everywhere.  Controls of a specific form can be referred to by name
>      with document.forms[…].elements["…"].

As I said previously, if you have:

<html>
...
<form name... method=POST action...>
<INPUT TYPE=TEXT NAME=aName VALUE="blah">
</form>
...
</html>

and then you replace the <INPUT> element :
<script>
...
// oldEl is the element, obtained via gEBI or whatever
newEl=document.createElement("input");
newEl.name="aName";
newEl.type="file";
oldEl.parentNode.replaceChild(newEl,oldEl);

console.log(document.forms[0].aName.);
...
</script>

IE 7 (and IE 8 in compatibility mode) both show a gracious bug. At the 
time I made the test I wrote nodeFind(), that does not fail with any 
known [by me] browser. IIRC there were cross-browsers problems with 
getElementsByTagName at the time - not sure of that, anyway.

[apologize mode ON]
the fact is, I have to deal with my incomplete knowledge of different 
implementations of ECMAscript, different Levels of W3C DOM, different 
behaviour of different browsers and, in general, incomplete knowledge 
/per se/ :-), and the difficulty to keep up with the browser's 
evolution. Consequently, I try to avoid risks of cross-browsers 
incompatibility (and right now a new class of problems seems to arise 
with new devices such as smartphone, tablets and God knows what else: 
adaptive web design for one...). I must choose: and "the better is enemy 
of the good" (old italian proverb) has been proven to be a useful rule 
of thumb for me. I sometimes feel like an illiterate trying to write a 
poem, but I must do my best with the scarce resources I have (and this 
is true for me as for everyone else - just "scarce" has a different 
meaning).

JFC, here are some issues I remember I had to face in last years, apart 
the previously described one:
- getElementsByName/getElementsByTagName not implemented
- mysterios bug in Opera in printing a frame
- bug in Opera in iframes readystate
- bug in IE about the test for the existence of a method in designmode
- bug in Firefox if trying to get a specific property of a window
- try... catch not implemented
- the old problem of knowing if a page is completely loaded and rendered

...and so on, I can't remember all of them. :-)

[apologize mode OFF]

>>
>> I know of that. But it is not an exercise. The scenario here is: a user
>> can post a message in a [kinda of] message system. Messages can have
>> attachments. If the author wants to edit the message he posted, he may
>> want to change the text or the attachment. So he has a button "change
>> attachment", and the input showing the name of the actual attachment
>> becomes a <file> to select another one and upload it. :-)
>
> (“Exercise” was not to be understood verbatim.)  See my correction.  There
> appears to be no point to use a read-only input[type="text"] element here if
> you want to support IE/MSHTML because you need to replace the element in any
> case.

? Not sure to understand. If the user only wants to change a description 
in the form (that reflects the content of a record in a database), the 
<submit> sends the form with no <file> control, so the CGI server side 
only updates the record. If a <file> control is present the CGI takes a 
different route, uploads the file, stores the file somewhere and writes 
the address to the database etc.

>>>
>>> There is no “javascript”.
>>
>> ECMA, ok, ECMA.
>
> There is no ECMA (anymore).  There are Ecma International, and the
> ECMAScript Language Specification (named for historical reasons).  But what
> matters more than the name is the fact that this specification has several
> *different* implementations; several of them have “JavaScript” in their
> name.

I meant "ECMA" as string substitution of "java". I sould have written:
s/Java/ECMA/

>
> I do not know xbase.  ECMAScript is a language of the C family, so you need
> to return a value from a function if you want to avoid an implicit return
> value.  The implicit return value is the “undefined” value in ECMAScript
> implementations.

ACK. See also my answer to Scott Sauyet

Dan

-- 
"Everybody should pay taxes with a smile"
I tried, but they want money.

[toc] | [prev] | [next] | [standalone]


#28467

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-25 14:11 +0200
Message-ID<1458271.t0pGGtDH7K@PointedEars.de>
In reply to#28456
danca (Daniele Campagna) wrote:

[Fixed quotation]

> […] But IIUC, I would need different functions for different elements,

Not necessarily.

> and maybe feature testing for getElementsByName...

Definitely.

> As I said previously, if you have:
> 
> […]
> 
> IE 7 (and IE 8 in compatibility mode) both show a gracious bug.

Which would be?  I must have missed that.

> At the time I made the test I wrote nodeFind(), that does not fail with 
> any known [by me] browser.

With *your* documents, in *your* environments.

> IIRC there were cross-browsers problems with
> getElementsByTagName at the time - not sure of that, anyway.

AISB, there could only be cross-browser problems with IE < 5.5.  Problems 
that are solvable with code.
 
> JFC, here are some issues I remember I had to face in last years, apart
> the previously described one:
> - getElementsByName/getElementsByTagName not implemented

Name one.

> - mysterios bug in Opera in printing a frame
> - bug in Opera in iframes readystate
> - bug in IE about the test for the existence of a method in designmode
> - bug in Firefox if trying to get a specific property of a window

Specify.

> - try... catch not implemented

Not since IE/MSHTML/JScript 5.5 and Mozilla 1.0.  See the ES Matrix.

> - the old problem of knowing if a page is completely loaded and rendered

Yes, but in most cases the problem with that was a wrong approach.
 
> ? Not sure to understand. If the user only wants to change a description
             ^^
_I_

> in the form (that reflects the content of a record in a database), the
> <submit> sends the form with no <file> control, so the CGI server side
> only updates the record. If a <file> control is present the CGI takes a
> different route, uploads the file, stores the file somewhere and writes
> the address to the database etc.

You cannot set the “type” property of “input” elements that are in the 
document, everywhere, so you need to replace the input[type="text"] with an 
input[type="file"] in any case.  So what do you need the (supposedly) *read-
only* input[type="text"] for in the first place?  Go with a div, or 
something like that, instead.

>>>> There is no “javascript”.
>>> ECMA, ok, ECMA.
>> […]
> 
> I meant "ECMA" as string substitution of "java". I sould have written:
> s/Java/ECMA/

That would not make a considerable change.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28470

From"danca (Daniele Campagna)" <cyberdanny@tiscalinet.it>
Date2015-07-25 21:22 +0200
Message-ID<mp0njk$10c$1@dont-email.me>
In reply to#28467
Il 07/25/2015 02:11 PM, Thomas 'PointedEars' Lahn ha scritto:

>>
>> IE 7 (and IE 8 in compatibility mode) both show a gracious bug.
>
> Which would be?  I must have missed that.

document.forms[n].<substitutedElementName>
or
document.forms[n][<substitutedElementName>]
return undefined.

>
>> At the time I made the test I wrote nodeFind(), that does not fail with
>> any known [by me] browser.
>
> With *your* documents, in *your* environments.

Correct. I just tried it on a large document downloaded from somewhere 
and it seems to fail (returns undefined). I'll try to understand why. 
Anyway it doesn't crash. :-)

>
>> JFC, here are some issues I remember I had to face in last years, apart
>> the previously described one:
>> - getElementsByName/getElementsByTagName not implemented
>
> Name one.

>
>> - mysterios bug in Opera in printing a frame
>> - bug in Opera in iframes readystate
>> - bug in IE about the test for the existence of a method in designmode
>> - bug in Firefox if trying to get a specific property of a window
>
> Specify.

I filed a report to Opera's guys, but it remained unanswered. I had a 
page with 2 frames and a couple of frames in turn in every "main" frame. 
Trying to print a sub-frame resulted in an empty page. I think this is 
true for all version with Presto.

With Opera 9.<something> IIRC I was trying to implement a function to 
load a html page in a DIV. I made the thing creating an hidden IFRAME 
and then copying the elements from the IFRAME to the DIV, but due to the 
inconsistent state of the onreadystatechange (IIRC) I wasn't able to 
detect when the IFRAME was completely loaded, so I had to resort to a 
workaround, injecting a script at the end of the IFRAME... there has 
been a thread here time ago about script injection.

In IE the test when a IFRAME is put in designmode queryCommandSupported 
or queryCommandEnabled (I don't remember the details) is wrongly 
implemented.

>
>> - try... catch not implemented
>
> Not since IE/MSHTML/JScript 5.5 and Mozilla 1.0.  See the ES Matrix.

Happily many problems have been solved, and now they are only ghosts of 
the past. Nevertheless when I started to tinker with ECMAscript 
implementations in browsers, the landscape was scaring. It is also 
possible I had access to incomplete/imprecise informations.

>
>> - the old problem of knowing if a page is completely loaded and rendered
>
> Yes, but in most cases the problem with that was a wrong approach.

The point being, it was complicated for a medium-weight programmer, very 
hard for a novice.

Anyway, of course you know better than me the incompatibilities, 
moreover I did not trace all the cats I had to skin, so my list is 
widely incomplete.

>
> You cannot set the “type” property of “input” elements that are in the
> document, everywhere, so you need to replace the input[type="text"] with an
> input[type="file"] in any case.  So what do you need the (supposedly) *read-
> only* input[type="text"] for in the first place?  Go with a div, or
> something like that, instead.

Not so easy, mr. Spock! :-)
Forms are generated server side by a general purpose function, and I 
implemented only form controls, so it would be messy to try to modify 
the function, while the Input element is supported, so I use an input 
(readonly) and I can live with it, as long as I can do a replaceChild(). 
In perspective, after discovering the IE bug and after having devised 
and written nodeFind() to circumvent it, I must admit that it would have 
been less work - but c'est la vie!..

Dan
-- 
"Everybody should pay taxes with a smile"
I tried, but they want money.

[toc] | [prev] | [next] | [standalone]


#28474

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-27 16:12 +0200
Message-ID<1598396.k6ieFuH4ol@PointedEars.de>
In reply to#28470
danca (Daniele Campagna) wrote:

> Il 07/25/2015 02:11 PM, Thomas 'PointedEars' Lahn ha scritto:
>>> IE 7 (and IE 8 in compatibility mode) both show a gracious bug.
>> Which would be?  I must have missed that.
> 
> document.forms[n].<substitutedElementName>
> or
> document.forms[n][<substitutedElementName>]
> return undefined.

Ah, that.  Yes, the workaround is to set the item of the collection 
yourself:

  newElement.name = "<substitutedElementName>";
  // […]
  document.forms[n]["<substitutedElementName>"] = newElement;

It is the same with (i)frames and maybe other element types.

>>> - mysterios bug in Opera in printing a frame
>>> - bug in Opera in iframes readystate
>>> - bug in IE about the test for the existence of a method in designmode
>>> - bug in Firefox if trying to get a specific property of a window
>> Specify.
> 
> […]

Thanks, I will review that later.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28508

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-08-08 04:50 +0200
Message-ID<mq3qpn$nn$1@solani.org>
In reply to#28433
On 15.07.2015 at 11:59, Thomas 'PointedEars' Lahn wrote:

> […]  And the proper approach here is iteration (walking the
> document tree), not recursion; because the stack size and/or nesting level 
> is limited (the Google Groups archive has test results), but an element’s 
> nesting level within a document tree is not.

Frankly, I do not get the point here.  Wouldn't the DOM implementation
have to *recursively* walk the DOM to find the desired elements as well?
 Of course, that would likely need less stack space than a recursive
*user-land* walk, but still be of the same order of magnitude.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#28509

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-08-08 09:33 +0200
Message-ID<1885256.KGaLaWtVka@PointedEars.de>
In reply to#28508
Christoph M. Becker wrote:

> On 15.07.2015 at 11:59, Thomas 'PointedEars' Lahn wrote:
>> […]  And the proper approach here is iteration (walking the
>> document tree), not recursion; because the stack size and/or nesting
>> level is limited (the Google Groups archive has test results), but an
>> element’s nesting level within a document tree is not.
> 
> Frankly, I do not get the point here.  Wouldn't the DOM implementation
> have to *recursively* walk the DOM to find the desired elements as well?

Not necessarily.  DOM Nodes have “firstChild”, “lastChild”, 
“previousSibling”, “nextSibling”, and “parentNode” properties [1]; in newer 
implementations, they also have “firstElementChild”, “lastElementChild”, 
“previousElementSibling”, “nextElementSibling”, and “parentElement” 
properties [2]; and an efficient implementation would maintain name-to-
element-list mappings.

>  Of course, that would likely need less stack space than a recursive
> *user-land* walk, but still be of the same order of magnitude.

To begin with, you are mistaken that I had referred to "the DOM 
implementation".  While there is W3C DOM Level 2 Traversal and Range [3] 
indeed, you can do an iterative "user-land" walk of the document tree as 
well; for example:

     grandparent ----------------.
   ,-- grandparent.firstChild <--'
   `---> grandparent.firstChild.firstChild ---------------.
  ,----- grandparent.firstChild.firstChild.nextSibling <--'
  `--> grandparent.firstChild.firstChild.nextSibling.parentNode.nextSibling 
--> END.

(The algorithm and implementation are left as an exercise to the reader.)

__________
[1] <http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-1950641247>
[2] <http://www.w3.org/TR/2015/WD-dom-20150618/#nodes>
[3] <http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html>
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28516

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-08-12 00:48 +0200
Message-ID<mqdu4i$sbr$1@solani.org>
In reply to#28509
On 08.08.2015 at 09:33, Thomas 'PointedEars' Lahn wrote:

> Christoph M. Becker wrote:
> 
>> On 15.07.2015 at 11:59, Thomas 'PointedEars' Lahn wrote:
>>
>>> […]  And the proper approach here is iteration (walking the
>>> document tree), not recursion; because the stack size and/or nesting
>>> level is limited (the Google Groups archive has test results), but an
>>> element’s nesting level within a document tree is not.
>>
>>  Of course, that would likely need less stack space than a recursive
>> *user-land* walk, but still be of the same order of magnitude.
> 
> To begin with, you are mistaken that I had referred to "the DOM 
> implementation".  While there is W3C DOM Level 2 Traversal and Range [3] 
> indeed, you can do an iterative "user-land" walk of the document tree as 
> well; for example:
> 
>      grandparent ----------------.
>    ,-- grandparent.firstChild <--'
>    `---> grandparent.firstChild.firstChild ---------------.
>   ,----- grandparent.firstChild.firstChild.nextSibling <--'
>   `--> grandparent.firstChild.firstChild.nextSibling.parentNode.nextSibling 
> --> END.
> 
> (The algorithm and implementation are left as an exercise to the reader.)

Seems to be rather trivial:

  grandparent.firstChild.nextSibling

I don't know, however, in which way this would help to find a *certain*
*node* somewhere in the DOM (which seems to be the topic of this thread,
if I'm not mistaken).  To do this, it is necessary to inspect all DOM
nodes (at least until the node which is looked for is found).  How can
this be done with an iterative algorithm?  Of course, by using an
explicit stack (which would be stored on the heap), and assuming that
the machine heap is much larger than the machine stack, indeed that
would allow to traverse more deeply nested trees...  at the cost of
runtime performance and a considerably more complex script.  Then again,
I can hardly imagine a recursive tree searching algorithm running out of
machine stack space on a reasonably sized DOM tree on somewhat
contempory browsers/machines.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#28517

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-08-12 01:18 +0200
Message-ID<4738754.gQ6MLv009L@PointedEars.de>
In reply to#28516
Christoph M. Becker wrote:

> On 08.08.2015 at 09:33, Thomas 'PointedEars' Lahn wrote:
>> […] you can do an iterative "user-land" walk of the document tree as
>> well; for example:
>> 
>>      grandparent ----------------.
>>    ,-- grandparent.firstChild <--'
>>    `---> grandparent.firstChild.firstChild ---------------.
>>   ,----- grandparent.firstChild.firstChild.nextSibling <--'
>>   `-->
>>   grandparent.firstChild.firstChild.nextSibling.parentNode.nextSibling
>> --> END.
>> 
>> (The algorithm and implementation are left as an exercise to the reader.)
> 
> Seems to be rather trivial:
> 
>   grandparent.firstChild.nextSibling

That is neither an algorithm nor an implementation :)
 
> I don't know, however, in which way this would help to find a *certain*
> *node* somewhere in the DOM (which seems to be the topic of this thread,
> if I'm not mistaken).  To do this, it is necessary to inspect all DOM
> nodes (at least until the node which is looked for is found).

Yes, in that regard not at all dissimilar to a recursive approach.

> How can this be done with an iterative algorithm?

You are the reader, you figure it out :-p

> Of course, by using an explicit stack (which would be stored on the heap),

No, the whole idea of an iterative approach is not to need a stack.  Hint: 
node.lastChild.nextSibling === null.

> Then again, I can hardly imagine a recursive tree searching algorithm
> running out of machine stack space on a reasonably sized DOM tree on 
> somewhat contempory browsers/machines.

What is your point?  If things were only as you wish them to be, if there 
were only “reasonably sized DOM trees” and “somewhat contemporary 
browsers/machines” in the wild, we would not have this discussion.  Either 
you are a defensive – and if I may say so, *logical* – programmer, 
considering the contingency that things are not necessarily, and in few 
cases are, as you wish them to be, or you are not.  I do not know about you, 
but I rather have slow code than code that breaks down when attempting to 
solved a problem.

JFTR: I would not use either an explicitly iterative nor an explicitly 
recursive approach as my preferred choice.  But the solution sought for was 
to be used as a fallback only, and *then* I choose the iterative approach 
because it cannot fail.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28525

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-08-13 23:26 +0200
Message-ID<mqj218$fvq$1@solani.org>
In reply to#28517
On 12.08.2015 at 01:18, Thomas 'PointedEars' Lahn wrote:

> Christoph M. Becker wrote:
> 
>> On 08.08.2015 at 09:33, Thomas 'PointedEars' Lahn wrote:
>>> […] you can do an iterative "user-land" walk of the document tree as
>>> well; for example:
>>>
>>>      grandparent ----------------.
>>>    ,-- grandparent.firstChild <--'
>>>    `---> grandparent.firstChild.firstChild ---------------.
>>>   ,----- grandparent.firstChild.firstChild.nextSibling <--'
>>>   `-->
>>>   grandparent.firstChild.firstChild.nextSibling.parentNode.nextSibling
>>> --> END.
>  
>> How can this be done with an iterative algorithm?
> 
> You are the reader, you figure it out :-p

Well, you have claimed "you can do an iterative "user-land" walk of the
document tree", so you may care to explain how. :)

I claim that it is not possible to do a purely iterative "user-land"
walk of the document tree, without resorting to let the DOM
implementation flatten the tree structure or by using an explicit (i.e.
user defined and maintained) stack/accumulator.  I am not able to prove
that, however.

FWIW, I might do something like the following:

    function eachChildOf(node, func) {
        node = node.firstChild;
        while (node) {
            func(node);
            eachChildOf(node, func);
            node = node.nextSibling;
        }
    }

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#28533

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-08-16 08:48 +0200
Message-ID<2800685.3l0yYTo2pD@PointedEars.de>
In reply to#28525
Christoph M. Becker wrote:

> On 12.08.2015 at 01:18, Thomas 'PointedEars' Lahn wrote:
>> Christoph M. Becker wrote:
>>> On 08.08.2015 at 09:33, Thomas 'PointedEars' Lahn wrote:
>>>> […] you can do an iterative "user-land" walk of the document tree as
>>>> well; for example: […]
>>>>
>>> How can this be done with an iterative algorithm?
>> You are the reader, you figure it out :-p
> 
> Well, you have claimed "you can do an iterative "user-land" walk of the
> document tree", so you may care to explain how. :)

I thought my illustration above in combination with what I said about the 
property values under certaining conditions was, well, illustrative.  
Perhaps you want to use a fixed-width font.  Simply handing out the 
algorithm would defeat the purpose of the exercise.

> I claim that […].  I am not able to prove that, however.

We can safely ignore it then.
 
> FWIW, I might do something like the following:
> 
>     function eachChildOf(node, func) {
               ^^^^^^^^^^^
>         node = node.firstChild;
>         while (node) {
>             func(node);
>             eachChildOf(node, func);
              ^^^^^^^^^^^^^^^^^^^^^^^^
>             node = node.nextSibling;
>         }
>     }

But that is recursion, and, as I indicated, you can do this without 
recursion.  Try again.
 
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28548

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2015-08-20 02:11 +0200
Message-ID<mr35v5$1jf$1@solani.org>
In reply to#28533
On 16.08.2015 at 08:48, Thomas 'PointedEars' Lahn wrote:

> I thought my illustration above in combination with what I said about the 
> property values under certaining conditions was, well, illustrative.  
> Perhaps you want to use a fixed-width font.  Simply handing out the 
> algorithm would defeat the purpose of the exercise.
> 
> […]  Try again.

Thanks for insisting. :)  Albeit this exercise still seems rather
somewhat academic to me, I found it interesting that it is indeed
possible to walk the DOM *tree* iteratively.  Apparently, I had
overlooked the Node::parentNode property which makes that possible.

A *simple* implementation of the iterative algorithm might be:

    function eachChildOf(baseNode, func) {
        var node = baseNode.firstChild;
        while (node) {
            func(node);
            if (node.firstChild) {
                node = node.firstChild;
            } else if (node.nextSibling) {
                node = node.nextSibling;
            } else {
                while (node.parentNode != baseNode &&
                        !node.parentNode.nextSibling) {
                    node = node.parentNode;
                }
                if (node.parentNode != baseNode) {
                    node = node.parentNode.nextSibling;
                } else {
                    break;
                }
            }
        }
    }

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#28452

FromScott Sauyet <scott.sauyet@gmail.com>
Date2015-07-18 15:59 -0700
Message-ID<4b1cb0ba-f0b0-4b25-a1aa-692c30e69833@googlegroups.com>
In reply to#28428
Thomas 'PointedEars' Lahn wrote:
> danca (Daniele Campagna) wrote:
> 
>> I wrote this small recursive function to find a node (having a name) in
>> a DOM element:
>> 
>> //usage: nodeFind (element to inspect (object), f.e. a form, name of the
>> element to search for, 3rd parameter empty at first call)
>> 
>> function nodeFind(el,n,retval){
>>   if (el.name==n) {
>>     return (el)
>>   } else {
>>     if (el.hasChildNodes) {
>>       for (var z=0;z<el.childNodes.length;++z){
>>         var a=el.childNodes.item(z);
>>         retval=nodeFind(a,n,retval)
>>       
>>     }
>>   }
>>   return retval
>> //^^^^^^^^^^^^ note!
>> }
> [ ... ]
> 
>> One strange thing is the way recursion is implemented in javascript: I
>> did not put the "return retval" statement at first, it seems unuseful,
>> and went crazy before discovering that it is needed.

That is not really an issue with recursion.  This has to do with the way
Javascript passes values to functions.  It uses a specialization of call 
by value, sometimes known as "call by sharing".  The reference the caller
has stored as `retval` is not passed to the function.  Instead a *copy*
of that reference is passed.  Both refer initially to the same object.
But when, inside the function, you reassign the new reference, the caller's reference is left alone.  This shouldn't be too surprising if you've dealt
with languages like Java, Ruby, Python, or even Scheme; they all use a
similar technique.


> There is no "javascript".  [ ... ]

Keep tilting at that windmill.  The rest of us know better.


> And the proper approach here is iteration (walking the 
> document tree), not recursion; because the stack size and/or nesting level 
> is limited (the Google Groups archive has test results), but an element's 
> nesting level within a document tree is not.

Recursion is logically correct here.  If you're working with modern browsers,
you'll have at least a 20000-call deep recursion stack..  If you have a tree
that deep in your document, heaven help you.  If you have to support IE6 - IE8,
you'll still get well over 1000 calls deep.  I don't know about you, but I've
never written a document with that much nesting.

A recursive solution is clear and elegant.  A non-recursive version would be
much less so.  If you make it tail-recursive, when browsers start to optimize
tail-recursion, the little performance penalty you would currently pay for
recursion will be eliminated. 

  -- Scott

[toc] | [prev] | [next] | [standalone]


#28457

From"danca (Daniele Campagna)" <cyberdanny@tiscalinet.it>
Date2015-07-21 12:30 +0200
Message-ID<mol6so$48v$1@dont-email.me>
In reply to#28452
Il 07/19/2015 12:59 AM, Scott Sauyet ha scritto:
> Thomas 'PointedEars' Lahn wrote:
>> danca (Daniele Campagna) wrote:
>>
>>> I wrote this small recursive function to find a node (having a name) in
>>> a DOM element:
>>>
>>> //usage: nodeFind (element to inspect (object), f.e. a form, name of the
>>> element to search for, 3rd parameter empty at first call)
>>>
>>> function nodeFind(el,n,retval){
>>>    if (el.name==n) {
>>>      return (el)
>>>    } else {
>>>      if (el.hasChildNodes) {
>>>        for (var z=0;z<el.childNodes.length;++z){
>>>          var a=el.childNodes.item(z);
>>>          retval=nodeFind(a,n,retval)
>>>
>>>      }
>>>    }
>>>    return retval
>>> //^^^^^^^^^^^^ note!
>>> }
>> [ ... ]
>>
>>> One strange thing is the way recursion is implemented in javascript: I
>>> did not put the "return retval" statement at first, it seems unuseful,
>>> and went crazy before discovering that it is needed.
>
> That is not really an issue with recursion.  This has to do with the way
> Javascript passes values to functions.  It uses a specialization of call
> by value, sometimes known as "call by sharing".  The reference the caller
> has stored as `retval` is not passed to the function.  Instead a *copy*
> of that reference is passed.  Both refer initially to the same object.
> But when, inside the function, you reassign the new reference, the caller's reference is left alone.  This shouldn't be too surprising if you've dealt
> with languages like Java, Ruby, Python, or even Scheme; they all use a
> similar technique.
>
>
I should have written "the way values are passed to functions".
Unfortunately I don't know any of the languages you are referring to.
In xBase (supposing to have an object mirroring the ECMAscript objects, 
and there is none in fact - but it should be possible to create one), I 
could have written:

element=nodeFind(el,n)

function nodeFind(el,n)(
  local z,a
  if el:name==n
   return (el)
  else
   if el:hasChildNodes
    for z=0 to el:childNodes:length
     a=el:childNodes:item(z)
     nodeFind(a,n)
    next z
  endif
return nil

This function (untested) should return the object (if found) or continue 
to call itself and if no match is found the final return value should be 
NIL.

Anyway thans for the explanation, that casts some light on the issue.

>> There is no "javascript".  [ ... ]
>
> Keep tilting at that windmill.  The rest of us know better.
>

:-)

>
> Recursion is logically correct here.  If you're working with modern browsers,
> you'll have at least a 20000-call deep recursion stack..  If you have a tree
> that deep in your document, heaven help you.  If you have to support IE6 - IE8,
> you'll still get well over 1000 calls deep.  I don't know about you, but I've
> never written a document with that much nesting.
>
> A recursive solution is clear and elegant.  A non-recursive version would be
> much less so.  If you make it tail-recursive, when browsers start to optimize
> tail-recursion, the little performance penalty you would currently pay for
> recursion will be eliminated.
>
>    -- Scott
>

"logically correct" is a part of your answer i like very much, but "a 
recursive solution is clear and elegant" is what really made my day ;-)

Dan
-- 
"Everybody should pay taxes with a smile"
I tried, but they want money.

[toc] | [prev] | [next] | [standalone]


#28459

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-07-21 13:53 +0200
Message-ID<1625412.DiW0shChWm@PointedEars.de>
In reply to#28457
danca (Daniele Campagna) wrote:

> Il 07/19/2015 12:59 AM, Scott Sauyet ha scritto:
>> Thomas 'PointedEars' Lahn wrote:
>>> There is no "javascript".  [ ... ]
>>
>> Keep tilting at that windmill.  The rest of us know better.
> 
> :-)

So *that* is what you *really* think.  Noted.

>> Recursion is logically correct here.

Nonsense.

>> If you're working with modern browsers, you'll have at least a 20000-call
>> deep recursion stack..

Cite evidence.

And if you are working with not so modern browsers, and not so shallow 
documents, which you cannot know because with scripting you do not know the 
environment your code will be exposed to, your code will *break*.  So 
actually you do not need to cite evidence; your argument is that of the 
blissfully ignorant again.

>> If you have a tree that deep in your document, heaven help you.

Memory is an issue, too.

>> If you have to support IE6 - IE8,
>> you'll still get well over 1000 calls deep.

It depends not only on the nesting level, but on the stack *size*.

>> I don't know about you, but I've never written a document with that much
>> nesting.
>>
>> A recursive solution is clear and elegant.  A non-recursive version would
>> be much less so.  If you make it tail-recursive, when browsers start to
>> optimize tail-recursion, the little performance penalty you would
>> currently pay for recursion will be eliminated.
> 
> "logically correct" is a part of your answer i like very much, but "a
> recursive solution is clear and elegant" is what really made my day ;-)

You are easily amused.  This "logic" is flawed.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.javascript


csiph-web