0

I've tried to replace occurences of string "blue" with "red" in the document using DOM methods. However, I have not got the desired result.

Here's the code I've tried:

<html>
  <body>
    <p>Click the button to replace "blue" with "red" in the paragraph below:</p>
    <div id="main">
      <p>Mr Blue has a blue house and a blue car.</p>
      <p>Mr Blue has a blue house and a blue car.</p>
    </div>
    <button onclick="myFunction()">Try it</button>
    <script>
      function myFunction() {
        var str = document.getElementById("main");
        var x = str.document.getElementsByTagName("p");
        var res = x.innerHTML.replace(/blue/gi, "red");
        document.getElementsByTagName("p").innerHTML = res;
      }
    </script>
  </body>
</html>
4
  • 3
    getElementsByTagName returns a NodeList; you need to loop. Commented Jul 1, 2014 at 3:08
  • X is not an object, but it is an array of objects in the page. please use x[0].innerHTML. yes, it should be a loop. just gave an example how it can be updated... Commented Jul 1, 2014 at 3:08
  • @Murtaza I think this should loop to change 'blue'. Commented Jul 1, 2014 at 3:11
  • i have used x[0].innerHTML still not working. I am a beginner to java script. Could you please explain what is a loop. Commented Jul 1, 2014 at 3:13

5 Answers 5

5

There are multiple problems in your code.

To get ps from the div, you need to:

str.getElementsByTagName("p");  // and not str.document...

The above statement will return a collection and not a single element. So you need to loop over the collection and do your replace.

for (var i = 0; i < x.length; i++) {
    var res = x[i].innerHTML.replace(/blue/gi, "red");
    x[i].innerHTML = res;
}

Working example.

Update based on your comment (what is a loop): Please use the tutorials here to get started.

Sign up to request clarification or add additional context in comments.

Comments

2

Another way to do it is to ignore the p tags altogether and just do the replacement on the div's innerHTML, like so:

function myFunction() {
    var str = document.getElementById("main");
    var inner = str.innerHTML;
    var res = inner.replace(/blue/gi, "red");
    str.innerHTML = res;
}
document.getElementsByTagName('button')[0].addEventListener('click', myFunction);
<div id="main">
  <p>Mr Blue has a blue house and a blue car.</p>
  <p>Mr Blue has a blue house and a blue car.</p>
</div>
<button>Try it</button>

Comments

1

getElementsByTagName returns a NodeList; you need to loop, using a for loop for example. But here's an alternative more re-usable approach that handles letter case:

// helper to convert NodeList to real array
var toArray = Array.call.bind([].slice)
// helper to query the DOM
var query = document.querySelectorAll.bind(document)

// uppercase first letter
var capitalize = function(x) {
  return x[0].toUpperCase() + x.slice(1)
}
// replace word and handle letter case
var replaceWord = function(word, replacement, str) {
  return str.replace(RegExp(word, 'gi'), function(m) {
    return /[A-Z]/.test(m) ? capitalize(replacement) : replacement
  })
}

// query all `p` tags and replace
toArray(query('p')).forEach(function(x) {
  x.textContent = replaceWord('blue', 'red', x.textContent)
})

Demo: http://jsbin.com/siveh/2/edit

Comments

1

This should work for you:

var paras = document.getElementsByTagName('p');
for (var i = 0; i < paras.length; i++) {
    paras[i].textContent = paras[i].textContent.replace(/blue/g,'red');
};

Comments

1

Couple of things:

  1. You can't call .document on str, which is already an object.
  2. You'll need to iterate through the array of p elements, which you were almost grabbing correctly. :)

Something like this:

function myFunction() {
    var str = document.getElementById("main");
    var x = str.getElementsByTagName("p");
    for (i = 0; i < x.length; i++) {
        var text = x[i].innerHTML;
        x[i].innerHTML = text.replace(/blue/gi, "red");
    }    
}

You can see a working example here: http://jsfiddle.net/a942G/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.