From: Denis McMahon on
At the moment I use named elements, and group the elements by giving
them a common name, but this feels "wrong". For example:

function vis(name, state)
{
var els = document.getElementsByName(name);
for (var el in els) els[el].style.visible = state;
}

Has anyone got a "better" way to do this sort of thing?

Rgds

Denis McMahon
From: Evertjan. on
Denis McMahon wrote on 10 aug 2010 in comp.lang.javascript:

> At the moment I use named elements, and group the elements by giving
> them a common name, but this feels "wrong". For example:
>
> function vis(name, state)
> {
> var els = document.getElementsByName(name);
> for (var el in els) els[el].style.visible = state;
>}
>
> Has anyone got a "better" way to do this sort of thing?
>

class

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
From: Denis McMahon on
On 10/08/10 21:57, Evertjan. wrote:
> Denis McMahon wrote on 10 aug 2010 in comp.lang.javascript:
>
>> At the moment I use named elements, and group the elements by giving
>> them a common name, but this feels "wrong". For example:
>>
>> function vis(name, state)
>> {
>> var els = document.getElementsByName(name);
>> for (var el in els) els[el].style.visible = state;
>> }
>>
>> Has anyone got a "better" way to do this sort of thing?

> class

Yes, nice answer, but how do you refer to a class to change it's style rule?

If I have to trawl through
document.styleSheets[*].cssRules|rules[*].selectorText looking for any /
every rule that matches my class to set the style element, that's not
really "better".

Rgds

Denis McMahon
From: Gregor Kofler on
Am 2010-08-11 05:30, schrieb Denis McMahon:
> On 10/08/10 21:57, Evertjan. wrote:
>> Denis McMahon wrote on 10 aug 2010 in comp.lang.javascript:
>>
>>> At the moment I use named elements, and group the elements by giving
>>> them a common name, but this feels "wrong". For example:
>>>
>>> function vis(name, state)
>>> {
>>> var els = document.getElementsByName(name);
>>> for (var el in els) els[el].style.visible = state;

This rather works by coincidence, since el will become any property of
your els collection - and quite a few of these properties won't have a
style property. (And most DOM elements don't have a name property.)

A working approach:

var l = els.length;
while(l--) {
els[l].style.visibility = state;
}

>>> }
>>>
>>> Has anyone got a "better" way to do this sort of thing?
>
>> class
>
> Yes, nice answer, but how do you refer to a class to change it's style rule?

You don't.

element.getElementsByClassName(cName) in recent enough browsers will
give you all elements with the according class. Rest of the solution
looks exactly like the one above.
If getElementsByClassName() is not available, a simple function will do
the job:

(untested)
function gEBCN(cN) {
var els = document.getElementsByTagName("*");
var result = [];
var l = els.length;

while(l--) {
if(els[l].className == cN) {
results.push(els[l]);
}
}
return result;
}

The main difference: the "native" gEBCN() will return a live collection,
the custom version a snapshot.

> If I have to trawl through
> document.styleSheets[*].cssRules|rules[*].selectorText looking for any /
> every rule that matches my class to set the style element, that's not
> really "better".

Obviously not.

Gregor
From: williamc on
On 8/11/2010 5:54 AM, Gregor Kofler wrote:
> Am 2010-08-11 05:30, schrieb Denis McMahon:
>> On 10/08/10 21:57, Evertjan. wrote:
>>> Denis McMahon wrote on 10 aug 2010 in comp.lang.javascript:
>>>
>>>> At the moment I use named elements, and group the elements by giving
>>>> them a common name, but this feels "wrong". For example:
>>>>
>>>> function vis(name, state)
>>>> {
>>>> var els = document.getElementsByName(name);
>>>> for (var el in els) els[el].style.visible = state;
>
> This rather works by coincidence, since el will become any property of
> your els collection - and quite a few of these properties won't have a
> style property. (And most DOM elements don't have a name property.)
>
> A working approach:
>
> var l = els.length;
> while(l--) {
> els[l].style.visibility = state;
> }
>
>>>> }
>>>>
>>>> Has anyone got a "better" way to do this sort of thing?
>>
>>> class
>>
>> Yes, nice answer, but how do you refer to a class to change it's style
>> rule?
>
> You don't.
>
> element.getElementsByClassName(cName) in recent enough browsers will
> give you all elements with the according class. Rest of the solution
> looks exactly like the one above.
> If getElementsByClassName() is not available, a simple function will do
> the job:
>
> (untested)
> function gEBCN(cN) {
> var els = document.getElementsByTagName("*");
> var result = [];
> var l = els.length;
>
> while(l--) {
> if(els[l].className == cN) {
> results.push(els[l]);
> }
> }
> return result;
> }
>
> The main difference: the "native" gEBCN() will return a live collection,
> the custom version a snapshot.
>
>> If I have to trawl through
>> document.styleSheets[*].cssRules|rules[*].selectorText looking for any /
>> every rule that matches my class to set the style element, that's not
>> really "better".
>
> Obviously not.
>
> Gregor

I was going to post this question myself (i.e. what's the best getEBCN
function?)...

Good point about the difference between the native implementation
returning a (live) node list vs. just a snapshot.

Any solution must work with multiple values, though, e.g. class="foo
bar" and I don't see how the function above will do that.

I've seen approaches like:

if native support
use native support
if xpath
use xpath
else
getEBTN(*)
var re = new RegExp("(^|\\s)"+className+"(\\s|$)");
loop and push matches onto an array

I think I've even seen some people include a QSA branch. Not sure if
that's a good idea.

Crockford suggested this (calling his recursive walkTheDom function)...

function getElemsByClassName2(className) {
if (document.getElementsByClassName) {
return(elem.getElementsByClassName(className));
} else {
var results = [];
walkTheDOM(document.body, function (node) {
var a, c = node.className, i;
if (c) {
a = c.split(' ');
for (i = 0; i < a.length; i += 1) {
if (a[i] === className) {
results.push(node);
break;
}
}
}
});
return results;
}
}


// this one is copied from the Sitepoint book...
function getElementsByClassNameXPath(className, context) {
context = context || document;
var els = [];
if (typeof document.evaluate == "function") {
var xpath = document.evaluate(".//*[ contains(concat(' ',
@class, ' '), ' " + className + " ')]", context, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < xpath.snapshotLength; i++ ) {
els.push(xpath.snapshotItem(i));
}
} else {
var nodelist = context.getElementsByTagName("*");
var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
els = Array.filter(nodeList, function(node) {
return node.className.match(re);
});
}
return els;
}

I saw a very long "ultimate" version somewhere (Robert Nyman?). I'd be
interested to see what people use in their own work.

--

--williamc
 |  Next  |  Last
Pages: 1 2 3 4 5
Prev: FYI: Douglas Crockford: Loopage
Next: Getting there....