выделение текста путем игнорирования внутренних элементов тега div javascript - PullRequest
4 голосов
/ 01 июня 2010
<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>

Ok. Позвольте мне объяснить -> метод getSelectionHTML () предназначен для выбора символов от 0 до 10. Я получаю значения по идентификатору "myDiv". но внутренние полужирные, курсивные и другие теги доставляют мне неприятности.

Проще говоря, я просто хочу выбрать первые десять символов (и применить их к тегу span), которые находятся в теге "myDiv".

Что именно мне не хватает?

Ответы [ 2 ]

2 голосов
/ 01 июня 2010

Это намного проще в IE, используя TextRange, который основан на символах, словах и предложениях, а не на узлах и смещениях. В браузерах, отличных от IE, вам придется утомительно обходить текстовые узлы вручную в DOM. Однако, даже если вы сделаете это, чтобы получить первые десять текстовых символов в вашем <div> (что будет «asdf asdfa»), ваша стратегия имеет недостатки, поскольку вы используете замену на innerHTML, которая будет пытаться и не может найти «asdf asdfa» (innerHTML будет начинаться с «asdf как <b> dfa» или, возможно, «asdf как <B>», в зависимости от браузера).

Я хотел бы предложить выполнить обход DOM, чтобы найти все текстовые узлы в пределах <div> и окружить части нужных вам текстовых узлов с помощью <span> s, таким образом, избегая диапазонов в целом и, следовательно, делая эту работу во всех основных браузеры.

1 голос
/ 01 июня 2010

Вы пытаетесь выбрать, например, символы с 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…
...