Список цитат ищется в тексте и выделяется цветом по клику, но поиск идет от начала и до последнего найденного элемента, а не по всем тексту, помогите


Поиск осуществляется по тексту до первой найденной цитаты, то есть переменная root содержит текст, меньший начального. Я не могу это исправить. Хотелось бы что бы поиск осуществлялся по всему тексту, на кнопки "Показать в тексте" можно было нажимать неограниченное количество раз.
function domRangeHighlight(text) {
$('div span').replaceWith(function(){
return $(this).text();
});
var root = document.getElementById('text').firstChild;
console.log(root);
var content = root.nodeValue;
console.log(content);
// Проверим есть ли совпадения с переданным текстом
if (content.indexOf(text) !== -1) {
if (document.createRange) {
var rng = document.createRange();
// Ставим верхнюю границу по индексу совпадения,
rng.setStart(root, content.indexOf(text));
// а нижнюю по индексу + длина текста
rng.setEnd(root, content.indexOf(text) + text.length);
// Создаём спан с синим фоном
var highlightDiv = document.createElement('span');
highlightDiv.style.backgroundColor = 'blue';
// Обернём наш Range в спан
rng.surroundContents(highlightDiv);
}
}
}
Форма HTML
<form action="/" method="post">
{% if text %}
<div id="text">{{text}}</div>
<a href="/">проверить другой текст</a>
{% else %}
<form action="/" method="post">
<textarea id = 'text' name="some_text"></textarea>
<input type="submit" value="Проверить" />
</form>
{% endif %}
</form>
Ответы (1 шт):
После того, как вы "обернули" фрагмент текста в теги <span>...</span>, первым потомком элемента root, который вы получите после вызова document.getElementById('text').firstChild, как раз и будет элемент типа Text, содержащий текст с его начала и до появления элемента <span>. Это конечно если предыдущее совпадение не случилось с самого начала текста, тогда первым потомком будет этот самый <span>. Насколько я понимаю, вы пытаетесь обойти это, превращая каждый элемент <span> в текст с помощью следующего фрагмента кода:
$('div span').replaceWith(function(){
return $(this).text();
});
Но вы не учитываете того, что в этом случае вы всё равно получаете в качестве "детей" элемента <div id="text"> три отдельных элемента типа Text - то, что было до элемента <span>, то, что было внутри элемента <span>, и то, что было после элемента <span>. Поэтому первым потомком всё равно остаётся только один из них. Так что советую вам выкинуть ваш jQuery подальше, и делать проще:
var txt = document.getElementById('text');
txt.textContent = txt.textContent;