Prev: FYI: Douglas Crockford: Loopage
Next: Getting there....
From: Denis McMahon on 10 Aug 2010 14:55 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 10 Aug 2010 16:57 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 10 Aug 2010 23:30 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 11 Aug 2010 05:54 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 11 Aug 2010 06:49
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 |