-->

Replace words of text area

2019-07-17 04:58发布

问题:

I have made a javascript function to replace some words with other words in a text area, but it doesn't work. I have made this:

function wordCheck() {
    var text = document.getElementById("eC").value;
    var newText = text.replace(/hello/g, '<b>hello</b>');
    document.getElementById("eC").innerText = newText;
}

When I alert the variable newText, the console says that the variable doesn't exist.
Can anyone help me?

Edit:
Now it replace the words, but it replaces it with <b>hello</b>, but I want to have it bold. Is there a solution?

回答1:

If <textarea>, then you need to use .value property.

document.getElementById("eC").value = newText;

And, as mentioned Barmar, replace() replaces only first word. To replace all word, you need to use simple regex. Note that I removed quotes. /g means global replace.

var newText = text.replace(/hello/g, '<b>hello</b>');


But if you want to really bold your text, you need to use content editable div, not text area:

<div id="eC" contenteditable></div>

So then you need to access innerHTML:

function wordCheck() {
    var text = document.getElementById("eC").innerHTML;
    var newText = text.replace(/hello/g, '<b>hello</b>');
    newText = newText.replace(/&lt;b&gt;&lt;b&gt;/g,"&lt;b&gt;");//These two lines are there to prevent <b><b>hello</b></b>
    newText = newText.replace(/&lt;\/b&gt;&lt;\/b&gt;/g,"&lt;/b&gt;");
    document.getElementById("eC").innerHTML = newText;
}


回答2:

Update:
In response to your edit, about your wanting to see the word "hello" show up in bold. The short answer to that is: it can't be done. Not in a simple textarea, at least. You're probably looking for something more like an online WYSIWYG editor, or at least a RTE (Richt Text Editor). There are a couple of them out there, like tinyMCE, for example, which is a decent WYSIWYG editor. A list of RTE's and HTML editors can be found here.

First off: As others have already pointed out: a textarea element's contents is available through its value property, not the innerText. You get the contents alright, but you're trying to update it through the wrong property: use value in both cases.

If you want to replace all occurrences of a string/word/substring, you'll have to resort to using a regular expression, using the g modifier. I'd also recommend making the matching case-insensitive, to replace "hello", "Hello" and "HELLO" all the same:

var txtArea = document.querySelector('#eC');
txtArea.value = txtArea.value.replace(/(hello)/gi, '<b>$1</b>');

As you can see: I captured the match, and used it in the replacement string, to preserve the caps the user might have used.

But wait, there's more:

What if, for some reason, the input already contains <b>Hello</b>, or contains a word containing the string "hello" like "The company is called hellonearth?" Enter conditional matches (aka lookaround assertions) and word boundaries:

txtArea.value = txtArea.value.replace(x.value.replace(/(?!>)\b(hello)\b(?!<)/gi, '<b>$1</b>');

fiddle

How it works:

  • (?!>): Only match the rest if it isn't preceded by a > char (be more specific, if you want to and use (?!<b>). This is called a negative look-ahead
  • \b: a word boundary, to make sure we're not matching part of a word
  • (hello): match and capture the string literal, provided (as explained above) it is not preceded by a > and there is a word boundary
  • (?!<): same as above, only now we don't want to find a matching </b>, so you can replace this with the more specific (?!<\/b>)
  • /gi: modifiers, or flags, that affect the entire pattern: g for global (meaning this pattern will be applied to the entire string, not just a single match). The i tells the regex engine the pattern is case-insensitive, ie: h matches both the upper and lowercase character.

The replacement string <b>$1</b>: when the replacement string contains $n substrings, where n is a number, they are treated as backreferences. A regex can group matches into various parts, each group has a number, starting with 1, depending on how many groups you have. We're only grouping one part of the pattern, but suppose we wrote:

'foobar hello foobar'.replace(/(hel)(lo)/g, '<b>$1-$2</b>');

The output would be "foobar <b>hel-lo</b> foobar", because we've split the match up into 2 parts, and added a dash in the replacement string.
I think I'll leave the introduction to RegExp at that... even though we've only scratched the surface, I think it's quite clear now just how powerful regex's can be. Put some time and effort into learning more about this fantastic tool, it is well worth it.