0

var list = [{
    name: "koala",
    owner: "mark"
  },

  {
    name: "opossum",
    owner: "lala"
  },

  {
    name: "dog",
    owner: "lucia"
  }
];



var str = document.body.innerHTML;
var toChange = /fox|penguin|cat/ig;


for (let listItem of list) {
  str = str.replace(toChange, listItem.name);
  str.id = 'span';
  document.body.innerHTML = str;
  console.log(listItem.name);
}
span {
  text-decoration: underline;
  color: red;
}
The fox jumps over the bush, the penguin walks, the cat drinks.

What I basically want to do is to replace the animals in the HTML text with the animals in "list". Additionally I want these last changed animal names to change color as well. I managed to replace with the animal Koala, but I am not really sure why it only replaces with Koala, as if I console.log(listItem.name) I get all three animals. Is there a problem with the for loop?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Nicoletta
  • 57
  • 10
  • Once you've replaced the animal names once, they no longer exist to be replaced again... – Robin Zigmond Jun 09 '20 at 20:52
  • 4
    Your regex matches all three of fox, penguin, and cat, globally (so, every instance of any of the three). So the first time around, they're all replaced with Koala. After that, it matches none, since it's all Koala all the time now. – Heretic Monkey Jun 09 '20 at 20:53
  • 1
    Does this answer your question? [How to replace multiple strings with other multiple strings at a time in javascript?](https://stackoverflow.com/questions/59222607/how-to-replace-multiple-strings-with-other-multiple-strings-at-a-time-in-javascr) – ggorlen Jun 09 '20 at 20:54
  • 2
    Note that strings don't have an `id` property, so setting `str.id = 'span'` does nothing, since you're not targeting an element, your targeting a string. – Heretic Monkey Jun 09 '20 at 20:55
  • Also, preferably find another way to avoid using regex on text nodes like this, but if you really need to, see [1](https://stackoverflow.com/questions/61198344/replace-all-instances-of-multiple-words-on-the-entire-page/61198587#61198587) and [2](https://stackoverflow.com/questions/59581570/whole-word-regex-matching-and-hyperlinking-in-javascript/59582082#59582082). It's definitely an antipattern, though, but better than `var str = document.body.innerHTML;` and then trying to manipulate the entire body in one regex shot, which [this](https://stackoverflow.com/questions/1732348/) applies to. – ggorlen Jun 09 '20 at 20:56

3 Answers3

2

I think this is what you want to do. As Heretic Monkey pointed out, using only one regex like that doesn't work. You can't set an id on a string. Also, ids must be unique, so you can't set the same id to various elements.

var list = [{
    name: "koala",
    owner: "mark"
  },

  {
    name: "opossum",
    owner: "lala"
  },

  {
    name: "dog",
    owner: "lucia"
  }
];

var str = document.body.innerHTML;
var toChange = [/fox/ig, /penguin/ig, /cat/ig];


for (let i = 0; i < list.length; i++) {
  str = str.replace(toChange[i], `<span>${list[i].name}</span>`);
  document.body.innerHTML = str;
  console.log(list[i].name);
}
span {
  text-decoration: underline;
  color: red;
}
The fox jumps over the bush, the penguin walks, the cat drinks.
D. Pardal
  • 6,173
  • 1
  • 17
  • 37
1

Replace the corresponding portion of your code with this:

var toChange = [/fox/ig, /penguin/ig, /cat/ig];

for (let listItem of list) {
  str = str.replace(toChange[list.indexOf(listItem)], listItem.name);

Result:

The koala jumps over the bush, the opossum walks, the dog drinks.
GirkovArpa
  • 4,427
  • 4
  • 14
  • 43
1

You are just replacing the whole HTML content not appending so you need to create a new span element and add that element in body also you can use innetText in place of innerHtml as innerHtml will give inner element as well with the text.

var list = [{
    name: "koala",
    owner: "mark"
  },

  {
    name: "opossum",
    owner: "lala"
  },

  {
    name: "dog",
    owner: "lucia"
  }
];
var htmlText = document.body.innerText;
var toChange = /fox|penguin|cat/ig;
var spanComponent='';
for (let listItem of list) {
  var str =  htmlText.replace(toChange, listItem.name);
  console.log(str)
  var span = document.createElement('span')
  span.innerText = str;
  document.body.appendChild(span);
}
The fox jumps over the bush, the penguin walks, the cat drinks.

Please run the snippet.

Nitesh Sharma
  • 545
  • 3
  • 14