Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #8254
| Path | csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!newsfeed.arcor.de!newsspool4.arcor-online.net!news.arcor.de.POSTED!not-for-mail |
|---|---|
| Content-Type | text/plain; charset="UTF-8" |
| Message-ID | <3002143.SPkdTlGXAF@PointedEars.de> (permalink) |
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
| Reply-To | Thomas 'PointedEars' Lahn <cljs@PointedEars.de> |
| Organization | PointedEars Software (PES) |
| Date | Sat, 12 Nov 2011 13:32:16 +0100 |
| User-Agent | KNode/4.4.11 |
| Content-Transfer-Encoding | 8Bit |
| Subject | Re: newbie Javascript checked is null or not an object |
| Newsgroups | comp.lang.javascript |
| References | <7a88bf5f-7821-49ca-85a8-bca655c28a36@u9g2000vbx.googlegroups.com> <4ebab172$0$14430$426a34cc@news.free.fr> <4ebb0ac7$0$28592$a8266bb1@newsreader.readnews.com> <1675485.FNyZMGkNft@PointedEars.de> |
| Followup-To | comp.lang.javascript |
| MIME-Version | 1.0 |
| Lines | 265 |
| NNTP-Posting-Date | 12 Nov 2011 13:32:17 CET |
| NNTP-Posting-Host | c56975e9.newsspool3.arcor-online.net |
| X-Trace | DXC=D^SBP@efGeKlU`@c^jLCbJMcF=Q^Z^V3H4Fo<]lROoRA8kF<OcfhCOKln[0CFce16JDZm8W4\YJNL;?f@h5gMfbLSn@YUKSOd=E:b7jm6OTmfB |
| X-Complaints-To | usenet-abuse@arcor.de |
| Xref | x330-a1.tempe.blueboxinc.net comp.lang.javascript:8254 |
Followups directed to: comp.lang.javascript
Show key headers only | View raw
Thomas 'PointedEars' Lahn wrote:
> Denis McMahon wrote:
>> var ff=document.form1.elements[elemnum]; // untested
>>
>> /* then wrap the tests so that it only looks for the checked property on
>> actual checkboxes */
>>
>> if (ff.type == "checkbox") ff.checked = !ff.checked; // untested
>
> […]
> However, this code should never be applied to objects that do not have a
> `checked' property in the first place, which renders the question moot and
> the test unnecessary.
>
>> You could even (and I'm sure someone will shortly post saying why this is
>> bad,
>
> It is bad,
>
>> but probably not actually explaining (a) why
>
> because it is comparably inefficient, incompatible, and unnecessary.
Now as to the why. Remember, the suggested alternative was (formatted):
var inputsInListcarsDiv =
document.getElementById("listcars").getElementsByTagName("input");
for (var i = 0; i < inputsInListcarsDiv.length; i++)
{
if (inputsInListcarsDiv[i].type == "checkbox")
{
inputsInListcarsDiv[i].checked = !inputsInListcarsDiv[i].checked;
}
}
Efficience
-----------
The suggested alternative is comparably inefficient because it requires a
lot more property lookups (P), calls (C) and operations (O). In order of
execution:
P: document
P: document.getElementById
C: document.getElementById("listcars")
P: document.getElementById("listcars").getElementsByTagName
C: document.getElementById("listcars").getElementsByTagName("input");
P: inputsInListcarsDiv
O: inputsInListcarsDiv =
document.getElementById("listcars").getElementsByTagName("input")
`for' statement:
P: i
O: i = 0
inputsInListcarsDiv.length times (any case):
P: i
P: inputsInListcarsDiv
P: inputsInListcarsDiv.length
O: ToBoolean(i < inputsInListcarsDiv.length)
P: inputsInListcarsDiv
P: inputsInListcarsDiv[i]
P: inputsInListcarsDiv[i].type
O: inputsInListcarsDiv[i].type == "checkbox"
inputsInListcarsDiv.length times (worst case):
P: inputsInListcarsDiv
P: inputsInListcarsDiv[i]
P: inputsInListcarsDiv[i].checked
O: !inputsInListcarsDiv[i].checked
P: inputsInListcarsDiv
P: inputsInListcarsDiv[i]
P: inputsInListcarsDiv[i].checked
O: inputsInListcarsDiv[i].checked = !inputsInListcarsDiv[i].checked
inputsInListcarsDiv.length times (any case):
P: i
O: i++
It is a lot more efficient when written as follows:
var inputsInListcarsDiv =
document.getElementById("listcars").getElementsByTagName("input");
for (var i = inputsInListcarsDiv.length; i--;)
{
var elem = inputsInListcarsDiv[i];
if (elem.type == "checkbox")
{
elem.checked = !elem.checked;
}
}
Then the following property lookups (P), calls (C) and operations (O) would
take place, in order of execution:
P: document
P: document.getElementById
C: document.getElementById("listcars")
P: document.getElementById("listcars").getElementsByTagName
C: document.getElementById("listcars").getElementsByTagName("input")
P: inputsInListcarsDiv
O: inputsInListcarsDiv =
document.getElementById("listcars").getElementsByTagName("input")
`for' statement:
P: i
P: inputsInListcarsDiv
P: inputsInListcarsDiv.length
O: i = inputsInListcarsDiv.length
inputsInListcarsDiv.length times (any case):
P: i
O: ToBoolean(i--)
P: inputsInListcarsDiv
P: inputsInListcarsDiv[i]
P: elem
O: elem = inputsInListcarsDiv[i]
P: elem.type
O: elem.type == "checkbox"
inputsInListcarsDiv.length times (worst case):
P: elem
P: elem.checked
P: elem
P: elem.checked
O: !elem.checked
O: elem.checked = !elem.checked
It is still very inefficient by comparison because it involves
- document.getElementById(), i.e. searching the entire document tree for one
element (best case), and returning the reference to the corresponding
element object,
and
- getElementsByTagName(), i.e. searching that element's subtree for
descendant elements of a certain type (), building a live collection
containing the corresponding element objects, and returning that
collection.
The `document.forms' collection, by comparison, is already a live collection
of objects representing `form' elements, and its `elements' collection is
already a live collection representing form controls of that particular
`form' element. Therefore, the first approach requires only the following,
in order of execution:
P: document
P: document.forms
P: document.forms["form1"]
P: document.forms["form1"].elements
P: elemnum
P: document.forms["form1"].elements[elemnum]
[a lot more P's, and O's, and one C]
However, it should be noted that none of those property accesses are
necessary here. One can pass `this' from an event handler attribute of a
control:
function toggleAll(ctrl, name)
{
var checked = ctrl.checked;
var checkboxes = ctrl.form.elements[name];
for (var i = checkboxes.length; i--;)
{
checkboxes[i].checked = checked;
}
}
<input type="checkbox" … onclick="toggleAll(this, 'foo')">
Which requires the following:
C: toggleAll(this, 'foo')
P: checked
P: ctrl
P: ctrl.checked
O: checked = ctrl.checked
P: ctrl
P: ctrl.form
P: ctrl.form.elements
P: name
P: ctrl.form.elements[name]
O: checkboxes = ctrl.form.elements[name]
`for' statement:
P: i
P: checkboxes
P: checkboxes.length
O: i = checkboxes.length
checkboxes.length times:
P: i
O: ToBoolean(i--)
P: checkboxes
P: i
P: checkboxes[i]
P: checked
O: checkboxes[i] = checked
In any case, one can easily see from this that this kind of element object
access must be more efficient (and cannot be less standards-compliant or
less compatible, see below) than the suggested alternative.
Compatibility
--------------
The suggested alternative is comparably incompatible, because not only it
relies on the availability of the document.getElementById() method, but also
on that element objects have a getElementsByTagName() method.
The document.getElementById(…) method was introduced with W3C DOM (HTML)
Level 1 [1]. But in that Specification, the HTMLElement interface has no
getElementsByTagName() method [2]. It was only introduced there with W3C
DOM Level 2 Core [3].
By contrast, the `forms' and `elements' collections [4,5] date back to the
so-called "DOM Level 0" [6] introduced by Netscape Navigator 3.0 [7,8] and
Internet Explorer 3.0 [9,10]. As a consequence of that, they can be
expected to be supported by any script-enabled HTML user agent.
Unnecessary
------------
Because we already have the `forms' and `elements' live collections in
either proprietary and standards-compliant implementation, it is not
necessary to search the entire document tree for suitable elements.
[x] done.
>> or (b) the 'proper' way of doing it)
[x] done.
PointedEars
_________
[1] <http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-26809268>
[2] <http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-011100101>
[3] <http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-745549614>
[4] <http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268>
[5] <http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357>
[6] <http://www.w3.org/TR/DOM-Level-2-HTML/glossary.html>
[7] <http://devedge-
temp.mozilla.org/library/manuals/2000/javascript/1.3/reference/document.html>
[8] <http://devedge-
temp.mozilla.org/library/manuals/2000/javascript/1.3/reference/form.html>
[9] <http://msdn.microsoft.com/en-us/library/ms531073(VS.85).aspx>
[10] <http://msdn.microsoft.com/en-us/library/ms535249(VS.85).aspx>
--
When all you know is jQuery, every problem looks $(olvable).
Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
newbie Javascript checked is null or not an object shall@uaex.edu - 2011-11-09 08:10 -0800
Re: newbie Javascript checked is null or not an object Elegie <elegie@anonymous.invalid> - 2011-11-09 17:59 +0100
Re: newbie Javascript checked is null or not an object Denis McMahon <denismfmcmahon@gmail.com> - 2011-11-09 23:20 +0000
Re: newbie Javascript checked is null or not an object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-10 14:30 +0100
Re: newbie Javascript checked is null or not an object Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-12 13:32 +0100
Re: newbie Javascript checked is null or not an object shall@uaex.edu - 2011-11-10 05:30 -0800
Re: newbie Javascript checked is null or not an object David Mark <dmark.cinsoft@gmail.com> - 2011-11-10 06:36 -0800
csiph-web