247

I want to replace the contents within a html element so I'm using the following function for that:

function ReplaceContentInContainer(id,content) {
   var container = document.getElementById(id);
   container.innerHTML = content;
}

ReplaceContentInContainer('box','This is the replacement text');

<div id='box'></div>

The above works great but the problem is I have more than one html element on a page that I want to replace the contents of. So I can't use ids but classes instead. I have been told that javascript does not support any type of inbuilt get element by class function. So how can the above code be revised to make it work with classes instead of ids?

P.S. I don't want to use jQuery for this.

William Jockusch
  • 26,513
  • 49
  • 182
  • 323
Taylor
  • 2,481
  • 2
  • 15
  • 4

12 Answers12

203

This code should work in all browsers.

function replaceContentInContainer(matchClass, content) {
    var elems = document.getElementsByTagName('*'), i;
    for (i in elems) {
        if((' ' + elems[i].className + ' ').indexOf(' ' + matchClass + ' ')
                > -1) {
            elems[i].innerHTML = content;
        }
    }
}

The way it works is by looping through all of the elements in the document, and searching their class list for matchClass. If a match is found, the contents is replaced.

jsFiddle Example, using Vanilla JS (i.e. no framework)

Randy the Dev
  • 25,810
  • 6
  • 43
  • 54
  • 5
    +1 - Good catch with the spaces, I always forget to do that... going to steal that for my answer ;) class is a reserved word in javascript though; you shouldn't use it for a variable name even though it really doesn't do any harm (yet). – Dagg Nabbit Sep 28 '10 at 00:36
  • 1
    @no with that function you don't have to have any content inside the element you want to replace. You can have a string in there or you can have it empty. Either way the replacement text will suddenly appear there when the function is called. – Taylor Sep 28 '10 at 00:47
  • @Andrew Dunn dude you rock, I got it to work and it actually works even in IE6, thanks a lot! – Taylor Sep 28 '10 at 00:50
  • 4
    Andrew, @no - Using `class` as a variable name does not work in Safari, so it does currently have an impact. – user113716 Sep 28 '10 at 00:50
  • 4
    The array returned by getElementsBytagName has also a length property, for which the className/indexOf test is then done as well. Although this is not a problem in this case, a regular for loop would be more correct. – Wolfgang Stengel Mar 06 '13 at 15:56
  • 1
    instead of indexOf with spaces, saving `elems[i].className` in, say `var cn` and using `cn && cn.match(new RegExp("(^|\\s)" + matchClass + "(\\s|$)"))` would work better because it matches any whitespace (space, non-breaking space, tab, etc.) while also allowing first/last class names to be matched. Example: http://jsfiddle.net/AXdtH/1636/ – Ky - Nov 30 '14 at 23:49
  • you should change the elements inner html outside of the loop. I ran into issue with this and had to create an array that I pushed these elements too and then changed their content after. I think if your content include html elements then it changes what elements you are iterated over and can mess things up. – Asher G. Dec 11 '14 at 22:54
  • 1
    -1 because this fails in the case where the classes in the `class` attribute are separated by some form of whitespace other than ordinary spaces, such as when a long list of classes has newlines in. – Mark Amery Jan 24 '16 at 15:54
190

Of course, all modern browsers now support the following simpler way:

var elements = document.getElementsByClassName('someClass');

but be warned it doesn't work with IE8 or before. See http://caniuse.com/getelementsbyclassname

Also, not all browsers will return a pure NodeList like they're supposed to.

You're probably still better off using your favorite cross-browser library.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
ColdCold
  • 4,181
  • 2
  • 26
  • 20
  • For IE8 you may use [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll). – Gras Double Jun 27 '17 at 07:22
123
document.querySelectorAll(".your_class_name_here");

That will work in "modern" browsers that implement that method (IE8+).

function ReplaceContentInContainer(selector, content) {
  var nodeList = document.querySelectorAll(selector);
  for (var i = 0, length = nodeList.length; i < length; i++) {
     nodeList[i].innerHTML = content;
  }
}

ReplaceContentInContainer(".theclass", "HELLO WORLD");

If you want to provide support for older browsers, you could load a stand-alone selector engine like Sizzle (4KB mini+gzip) or Peppy (10K mini) and fall back to it if the native querySelector method is not found.

Is it overkill to load a selector engine just so you can get elements with a certain class? Probably. However, the scripts aren't all that big and you will may find the selector engine useful in many other places in your script.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Cristian Sanchez
  • 31,171
  • 11
  • 57
  • 63
  • @Taylor: I think it works in IE8 (not 100% sure - too lazy to google it). Regardless, I added some info regarding backwards compatibility using third party selector engines. – Cristian Sanchez Sep 28 '10 at 00:32
  • 19
    `document.querySelector` works in IE8 and above: http://caniuse.com/queryselector – Zeke Dec 21 '12 at 04:38
26

A Simple and an easy way

var cusid_ele = document.getElementsByClassName('custid');
for (var i = 0; i < cusid_ele.length; ++i) {
    var item = cusid_ele[i];  
    item.innerHTML = 'this is value';
}
kta
  • 19,412
  • 7
  • 65
  • 47
6

I'm surprised there are no answers using Regular Expressions. This is pretty much Andrew's answer, using RegExp.test instead of String.indexOf, since it seems to perform better for multiple operations, according to jsPerf tests.
It also seems to be supported on IE6.

function replaceContentInContainer(matchClass, content) {
    var re = new RegExp("(?:^|\\s)" + matchClass + "(?!\\S)"),
        elems = document.getElementsByTagName('*'), i;
    for (i in elems) {
        if (re.test(elems[i].className)) {
            elems[i].innerHTML = content;
        }
    }
}

replaceContentInContainer("box", "This is the replacement text.");

If you look for the same class(es) frequently, you can further improve it by storing the (precompiled) regular expressions elsewhere, and passing them directly to the function, instead of a string.

function replaceContentInContainer(reClass, content) {
    var elems = document.getElementsByTagName('*'), i;
    for (i in elems) {
        if (reClass.test(elems[i].className)) {
            elems[i].innerHTML = content;
        }
    }
}

var reBox = /(?:^|\s)box(?!\S)/;
replaceContentInContainer(reBox, "This is the replacement text.");
Community
  • 1
  • 1
afsantos
  • 5,178
  • 4
  • 30
  • 54
4

This should work in pretty much any browser...

function getByClass (className, parent) {
  parent || (parent=document);
  var descendants=parent.getElementsByTagName('*'), i=-1, e, result=[];
  while (e=descendants[++i]) {
    ((' '+(e['class']||e.className)+' ').indexOf(' '+className+' ') > -1) && result.push(e);
  }
  return result;
}

You should be able to use it like this:

function replaceInClass (className, content) {
  var nodes = getByClass(className), i=-1, node;
  while (node=nodes[++i]) node.innerHTML = content;
}
Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
3

var elems = document.querySelectorAll('.one');

for (var i = 0; i < elems.length; i++) {
    elems[i].innerHTML = 'content';
};
Roger Causto
  • 153
  • 1
  • 3
  • 4
    That's not really an answer. Please try to [explain your code](http://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code-only-ques). Furthermore, it's basically a more compact version of another answer to this question that was posted 5 years ago. – helmbert May 12 '15 at 15:45
  • I dont know what is the problem. This answer is ok. There is no comment... and what? This is not gold rule. And what you want comment here? And [But is it readable code?](http://meta.stackexchange.com/questions/95470/down-vote-code-only-answers#answer-95473) – AntiCZ Jul 23 '15 at 10:56
3

I assume this was not a valid option when this was originally asked, but you can now use document.getElementsByClassName('');. For example:

var elements = document.getElementsByClassName(names); // or:
var elements = rootElement.getElementsByClassName(names);

See the MDN documentation for more.

thornjad
  • 155
  • 1
  • 13
3

There are 3 different ways to get elements by class in javascript. But here for your query as you have multiple elements with the same class names you can use 2 methods:

  1. getElementsByClassName Method - It returns all the elements with the specified class present in the document or within the parent element which called it.

    function ReplaceContentInContainer(className, content) {
        var containers = document.getElementsByClassName(className);
        for (let i = 0; i < containers.length; i++) {
            containers[i].innerHTML = content;
        }
    }
    ReplaceContentInContainer('box', 'This is the replacement text');
    
    <div class='box'></div>
    
  2. querySelectorAll Method - It select element on the basic of CSS selectors. Pass your CSS class to it with a dot and it will return all the element having specified class as an array-like object.

    function ReplaceContentInContainer(className, content) {
        var containers = document.querySelectorAll(`.${className}`);
        for (let i = 0; i < containers.length; i++) {
            containers[i].innerHTML = content;
        }
    }
    ReplaceContentInContainer('box', 'This is the replacement text');
    
    <div class='box'></div>
    
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Satish Chandra Gupta
  • 2,970
  • 1
  • 22
  • 22
0

I think something like:

function ReplaceContentInContainer(klass,content) {
var elems = document.getElementsByTagName('*');
for (i in elems){
    if(elems[i].getAttribute('class') == klass || elems[i].getAttribute('className') == klass){
        elems[i].innerHTML = content;
    }
}
}

would work

KeatsKelleher
  • 10,015
  • 4
  • 45
  • 52
-2

jQuery handles this easy.

let element = $(.myclass);
element.html("Some string");

It changes all the .myclass elements to that text.

Julian
  • 33,915
  • 22
  • 119
  • 174
-15

When some elements lack ID, I use jQuery like this:

$(document).ready(function()
{
    $('.myclass').attr('id', 'myid');
});

This might be a strange solution, but maybe someone find it useful.

The Krotek
  • 383
  • 1
  • 7
  • 3
    If there are multiple elements with class `myclass`, all of them will obtain the id `myid`, but ids should be unique! Moreover, OP explicitly says to avoid jQuery. – Oriol Jun 22 '14 at 23:27
  • 1
    It's not hard to add a foreach() clause and increment ID, if you have multiple elements of the same class. I added this solution as an alternative for those, who can use jQuery. OP already got a bunch of suitable answers anyway :-) – The Krotek Jun 23 '14 at 07:33