My table's <td>
s contains multiple classes. I would need to find every <td>
that contains the given string.
For example:
<table>
<tr>
<td class="hello there">foo</td>
<td class="hello here">bar</td>
<td class="not hello">baz</td>
</tr>
</table>
I would need to find every td containing "hello".
Can it be done? The simple className ==
will only return exact matches. Of course.
My table's <td>
s contains multiple classes. I would need to find every <td>
that contains the given string.
For example:
<table>
<tr>
<td class="hello there">foo</td>
<td class="hello here">bar</td>
<td class="not hello">baz</td>
</tr>
</table>
I would need to find every td containing "hello".
Can it be done? The simple className ==
will only return exact matches. Of course.
- Seems like I asked something very trivial, sorry. I just couldn't find it. Not like it would hurt (people can just find the answer on this site through Google.) Thank you. – Apache Commented Oct 28, 2012 at 19:15
- No worry. You could accept the first to have answered and this will be finished without fuss :) – Denys Séguret Commented Oct 28, 2012 at 19:16
8 Answers
Reset to default 3That's what getElementsByClassName
is for:
document.getElementsByClassName('hello');
This'll select any elements that have the class hello
.
Note: The class
attribute contains a space separated list of class names.
If you need to support IE8 and below, use this:
var elements = document.getElementsByTagName("td"),
helloElements = [],
i = elements.length;
for (i--) {
if ( ~(' ' + elements[i].className + ' ').indexOf(' hello ') ) {
helloElements.push(elements[i]);
}
}
Here's a demo: http://jsfiddle/AJEsp/
As per @mplungjan's suggestion, here's a short explanation of the bitwise tilde (~) trick:
The indexOf
function returns an integer with the position of the found substring, so that 'abc'.indexOf('b')
will return 1
, 'abc'.indexOf('c')
will return 2
, and so forth. If the substring is not found, it will return -1
.
The ~
character is one of the bitwise operators whcih inverts all the bits. Sidestepping the plicated issue of how exactly this happens, all we need to know now is that ~-1
returns 0
, while using the tilde on anything else would return a truthy value.
So, ~'str'.indexOf('substring')
can be treated as a Boolean of whether the substring was found.
Use something like this:
var tds = document.getElementsByTagName("td");
for (var i = 0; i < tds.length; i++) {
var cur = tds[i];
var the_class = cur.className;
if (the_class.split(" ").indexOf("hello") > -1) {
// cur has the class "hello"
}
}
There are other solutions though.
You can use the .classList
attribute that isn't pletely supported yet - https://developer.mozilla/en-US/docs/DOM/element.classList .
You can use document.getElementsByClassName
- https://developer.mozilla/en-US/docs/DOM/document.getElementsByClassName .
You can use document.querySelectorAll
- https://developer.mozilla/en-US/docs/DOM/Document.querySelectorAll .
var td_with_class = document.querySelectorAll("td.hello");
class="hello there"
means that the td has two classes, hello
and there
.
So you could use
var elements = document.getElementsByClassName('hello');
var tds = document.getElementsByTagName('td'),
filtered = [];
for (var i = 0; i < tds.length; i++){
if (tds[i].className.match(/\bhello\b/i)){
filtered.push(tds[i]);
}
}
Use RegExp
match and the \b
symbol to match tds with that specified class. Alternatively, you can backwards filter starting with class and filtering by tagName
:
var hellos = document.getElementsByClassName('hello'),
filtered = [];
for (var i = 0; i < hellos.length; i++){
if (hellos[i].tagName == 'TD'){
filtered.push(hellos[i]);
}
}
A general solution would be to get all items by tagname ("td"). Iterate over each item and determine if hello is a substring of the class attribute. Let me know if you need the code!
Amazingly no one suggested jQuery hasClass
Or just
var allHello = $("td.hello");
There is the .classList
property.
elem.classList.contains( 'hello' )
returns whether the element contains the "hello"
class.
Live demo: http://jsfiddle/E7jMt/1/
.classList
is implemented in all browsers (as of two days ago), but not in older version os IE (<10).
https://developer.mozilla/en-US/docs/DOM/document.getElementsByClassName
Get all elements that have both the 'red' and 'test' classes
document.getElementsByClassName('red test');
And to limit it to a certain node:
Find all div elements that have a class of 'test'
var tests = Array.prototype.filter( document.getElementsByClassName('test'), function(elem){ return elem.nodeName == 'TD'; });