Just like in jQuery we can use $(\".classname\"), is there a similar thing in javascript as well? Or if we don\'t have such method then how can i implement that.
Accordi
Unfortunately not consistently between browsers. If you don't need all of jQuery, but still would like to do selection based on CSS selectors, take a look at Sizzle, the selector library jQuery uses.
Another good implementation of getElementsByClassName
Mixes an XPath and DOM implementation; using XPath wherever possible.
if (!('getElementsByClassName' in document)) {
document.getElementsByClassName = function(className, parentElement) {
if (Prototype.BrowserFeatures.XPath) {
var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
return document._getElementsByXPath(q, parentElement);
} else {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [],
child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (Element.hasClassName(child, className)) elements.push(Element.extend(child));
}
return elements;
}
};
}
Yes, you'd have to iterate to support all browsers. If you do, tho, make sure you take advantage of the browser's built in functionality where it exists:
if(document.getElementsByClassName) {
return document.getElementsByClassName(className);
} else {
// iterate
}
Other than that, I'm with Jochen; use a framework
Some browsers, for example Firefox 3 support getElementsByClassName, others you have to iterate though all the tags, so if you wanted to support all browsers with a single function you should use the iterative method.
The best solution is to use jQuery or any other framework which will use the best available method.
i will have to iterate through all tags and then collect all elements which are having the same class as specified.
Yes. There are a couple of ways to improve the function from the page you linked, though:
RegExp-escape class names passed in so that it isn't broken by punctuation in the class name. For example a call to getElementsByClassName('ab.cd')
shouldn't match class="abxcd"
.
The HTML5 specification that defines getElementsByClassName
allows multiple space-separated class names, all of which have to be present on the element to match. Implement this.
optionally, allow a hint of tag name to be passed in to narrow down the number of elements the function has to look through for the common case where only one type of tag is affected. (This will do nothing on a real browser-native getElementsByClassName
call, so you shouldn't rely on it to filter out elements you don't want.)
Example implementation:
if (!('getElementsByClassName' in document)) {
document.getElementsByClassName= function(classnames, taghint) {
var exps= classnames.split(/\s+/).map(function(name) {
name= name.replace(/([/\\^$*+?.()|[\]{}])/g, '\\$1');
return new RegExp('(^|\\s)'+name+'(\\s|$)');
});
var els= this.getElementsByTagName(taghint || '*');
var matches= [];
for (var i= 0, n= this.length; i<n; i++)
var el= els[i];
if (exps.every(function(exp) {
return exp.test(el.className);
}))
matches.push(el);
}
return matches;
};
}
However this does also use a couple of ECMAScript Fifth Edition (or JavaScript 1.6) Array methods which IE doesn't yet have either, so you'd have to add fallback implementations for those, too:
if (!('map' in Array.prototype)) {
Array.prototype.map= function(mapper, that) {
var other= new Array(this.length);
for (var i= 0, n= this.length; i<n; i++)
if (i in this)
other[i]= mapper.call(that, this[i], i, this);
return other;
};
}
if (!('every' in Array.prototype)) {
Array.prototype.every= function(tester, that) {
for (var i= 0, n= this.length; i<n; i++)
if (i in this && !tester.call(that, this[i], i, this))
return false;
return true;
};
}