我有两个用HTML编写的textareas:
<textarea id="checked-words"></textarea>
<br />
<textarea id="words" onkeyup="displayColoredText()"></textarea>
<div id="text-to-insert"></div>
(进入div
元素,我将使用JavaScript
)
我的任务是在div
部分写入第二个textarea
中的文字,并将第一个textarea
中字符串的出现设为红色。
示例
如果第一个textarea
包含以下字词:aaa
,aab
,第二个包含aaab
,则所有字符都必须为红色。如果第二个包含abaa,则div
部分中的所有字符都不会为红色。
这是我的JavaScript
函数,用于显示和着色文本:
function displayColoredText() {
//Displays the colored text below the second textarea
//Find the two textareas
var firstTextArea = document.getElementById('checked-words');
var secondTextArea = document.getElementById('words');
//Split by spaces
var checkedWords = firstTextArea.value.split(" ");
var text = secondTextArea.value.split(" ");
var textToInsert = secondTextArea.value;
for(i in checkedWords) {
console.log(checkedWords.length);
textToInsert = textToInsert.replace(new RegExp(checkedWords[i], 'g'), '<span class="insertRed">' + checkedWords[i] + '</span>');
}
document.getElementById('text-to-insert').innerHTML = textToInsert;
}
我的问题是,如果第一个textarea
包含aaa
和aab
且第二个包含{{1},则不会考虑已替换的文本只有前三个字符是红色的,而不是整个字符串。我该如何解决这个问题?
答案 0 :(得分:2)
来自第二个文本区域的原始输入是纯文本,而不是HTML,因此这是&#34;状态&#34;您想要执行此操作的数据。
这将是我在评论中提到的实现它的方式,记录哪些位置首先匹配,然后简单地循环遍历所有字符以将它们包装在每个范围中:
function displayColoredText() {
//Displays the colored text below the second textarea
//Find the two textareas
var firstTextArea = document.getElementById('checked-words');
var secondTextArea = document.getElementById('words');
//Split by spaces
var checkedWords = firstTextArea.value.split(" ");
var text = secondTextArea.value;
// empty array with keys 0 to length-1 set to undefined
var markedMatches = new Array(secondTextArea.value.length);
for (var i = 0, l = checkedWords.length; i < l; ++i) {
var checkedWord = checkedWords[i],
start = 0,
matchPos;
// check for match from current starting position
while ((matchPos = text.indexOf(checkedWord, start)) !== -1) {
// mark positions from current match start to that plus length of match
for (var k = matchPos, m = matchPos + checkedWord.length; k < m; ++k) {
markedMatches[k] = true;
}
// advance starting position to continue searching
start = matchPos + 1;
}
}
var textToInsert = '';
for (var i = 0, l = text.length; i < l; ++i) {
// wrap in span if markedMatches contains true at this position
textToInsert += (markedMatches[i] ? '<span class="match">' + text[i] + '</span>' : text[i]);
}
document.getElementById('text-to-insert').innerHTML = textToInsert;
}
https://jsfiddle.net/t9xjzkaw/
正如我所说的那样,你可以更精确地将匹配作为间隔收集,或者将多个相邻的匹配字符放入单个span元素中,而不是将每个匹配字符单独包装......但这可以完成基本工作。 / p>
答案 1 :(得分:0)
您的问题是如何更换字符串。你的第一个字符串是'aaa aab'。在'aaab'中替换'aaa'后,你得到'&lt; span class =“insertRed”&gt; aaa&lt; / span&gt; b'。试图在这个字符串中找到'aab'将没有结果。你必须从你的原始字符串替换,并以某种方式将两者结合起来。我不知道该怎么做,但我希望这能让你走上正轨。
编辑: 我认为这会奏效: 不是替换字符串中的文本,而是将起始坐标放在数组中,将结束坐标放在第二个数组中。为找到的每个单词继续这样做。然后在所有开始坐标处插入字符串'&lt; span class =“insertRed”&gt;'。在所有结束坐标处,插入字符串'&lt; span&gt;'。这是JS:
function displayColoredText() {
//Displays the colored text below the second textarea
//arrays with coordinates
var beginnings = [];
var ends = [];
//Find the two textareas
var firstTextArea = document.getElementById('checked-words');
var secondTextArea = document.getElementById('words');
//Split by spaces
var checkedWords = firstTextArea.value.split(" ");
var text = secondTextArea.value.split(" ");
var textToInsert = firstTextArea.value;
for(i in checkedWords) {
console.log(checkedWords.length);
if (firstTextArea.value.indexOf(checkedWords[i]) != -1) {
beginnings.push(firstTextArea.value.indexOf(checkedWords[i]));
ends.push(firstTextArea.value.indexOf(checkedWords[i]) + checkedWords[i].length);
}
}
beginnings.sort(function(a, b){return b-a});
ends.sort(function(a, b){return b-a});
for (b in beginnings) {
textToInsert = textToInsert.slice(0, ends[b]) + "</span>" + textToInsert.slice(ends[b]);
textToInsert = textToInsert.slice(0, beginnings[b]) + '<span class="insertRed">' + textToInsert.slice(beginnings[b]);
}
document.getElementById('text-to-insert').innerHTML = textToInsert;
}
此代码未经测试,请告诉我,如果某些内容不起作用,我会更改它。基本上,我正在做的不是替换事件,而是先找到它们,将它们放在数组中,然后在这些坐标处插入正确的文本。我希望这有帮助!