Выделение текста путем игнорирования внутренних элементов тега div javascript
<html>
<body>
<script language="javascript">
function getSelectionHTML()
{
var div = document.getElementById("myDiv");
if (document.createRange) {
var textNode=div.firstChild;
var rangeObj=document.createRange();
rangeObj.setStart(textNode,0);
rangeObj.setEnd(textNode,5);
div .innerHTML = div .innerHTML.replace(rangeObj.toString(), '<span style="background-color: lime">'+rangeObj.toString()+'</span>')
}
}
</script>
<div id="myDiv">
asdf as<b>dfas df asf asdf sdfjk dvh a sjkh jhcdjkv</b> iof scjahjkv ahsjv hdjk biud fcsvjksdhf k
</div>
<form name="aform">
<input type="button" value="Get selection" onclick="getSelectionHTML()">
</body>
</html>
Хорошо. Позвольте мне объяснить -> метод getSelectionHTML() предназначен для выбора символов от 0 до 10. Я получаю значения по идентификатору "myDiv". но внутренние полужирные, курсивные и другие теги доставляют мне неприятности.
Проще говоря, я просто хочу сделать выбор из первых десяти символов (и применить их к тегу span), которые находятся в теге "myDiv".
Что именно мне не хватает?
2 ответа
Вы пытаетесь выбрать, например, символы от 1 до 10 вашего текста. Но при использовании Range.setStart
а также .endStart
Первый параметр - это текстовый узел, содержащий ваш текст. Если вы просматриваете DOM с помощью Firebug (или Web Inspector), вы заметите, что символ 10 вашего текста находится в другом элементе (<b>
элемент), с собственным текстовым узлом.
Кстати, вы пропустили несколько обязательных элементов / тегов, которые также могут быть источником ошибок.
Моя исправленная версия читает
<!DOCTYPE html>
<html>
<head>
<title>Title element is required</title>
<body>
<script>
function getSelectionHTML()
{
var div = document.getElementById("myDiv");
var bEl = document.getElementById("bEl");
if (document.createRange) {.
var textNode=div.firstChild;
var rangeObj=document.createRange();
rangeObj.setStart(textNode,0);
rangeObj.setEnd(bEl.firstChild,2);
alert(rangeObj.toString());
// div.innerHTML = div.innerHTML.replace(rangeObj.toString(), '<span style="background-color: lime">'+rangeObj.toString()+'</span>');
}
}
</script>
<div id="myDiv">
asdf as<b id="bEl">dfas df asf asdf sdfjk dvh a sjkh jhcdjkv</b> iof scjahjkv ahsjv hdjk biud fcsvjksdhf k
</div>
<form name="aform">
<input type="button" value="Get selection" onclick="getSelectionHTML()">
</form>
</body>
</html>
Сейчас rangeObj
содержит выделенный текст, но вы не можете просто вставить <span>
элемент, как вы пытались, потому что элементы не могут быть вложены таким образом:
<span>asdf as<b>dfa</span>s df asf…
Это намного проще в использовании IE TextRange
, который основан на символах, словах и предложениях, а не на узлах и смещениях. В браузерах, отличных от IE, вам придется утомительно обходить текстовые узлы вручную в DOM. Однако, даже если вы должны были сделать это, чтобы получить первые десять текстовых символов в вашем <div>
(что будет "asdf asdfa"), ваша стратегия имеет недостатки, потому что вы используете замену на innerHTML
, который попытался бы и не смог найти "asdf asdfa" (innerHTML
будет начинаться с "asdf как<b>
dfa "или, возможно," asdf как<B>
", в зависимости от браузера).
Я хотел бы предложить выполнить обход DOM, чтобы найти все текстовые узлы в пределах <div>
и окружая части текстовых узлов, которые вам нужны <span>
s, таким образом, избегая диапазонов в целом и, следовательно, заставляя это работать во всех основных браузерах.