Как я могу выделить текст объекта DOM Range?

Я выбираю какой-либо текст на странице html (открыт в firefox) с помощью мыши и используя функции javascript, я создаю/получаю объект rangeobject, соответствующий выбранному тексту.

 userSelection =window.getSelection(); 
 var rangeObject = getRangeObject(userSelection);

Теперь я хочу выделить весь текст, который подпадает под rangeobject.I делаю это, как это,

  var span = document.createElement("span");
  rangeObject.surroundContents(span);
  span.style.backgroundColor = "yellow";

Хорошо, это прекрасно работает, только когда rangeobject (начальная точка и конечная точка) находится в одном текстовом поле, затем выделяет соответствующий текст. Ex

    <p>In this case,the text selected will be highlighted properly,
       because the selected text lies under a single textnode</p>

Но если rangeobject охватывает более одного текстового блока, то он не работает должным образом, он выделяет только тексты, которые лежат в первом текстовом поле, Ex

 <p><h3>In this case</h3>, only the text inside the header(h3) 
  will be highlighted, not any text outside the header</p> 

Любая идея, как я могу сделать, все тексты, которые попадают под диапазон, выделены, независимо от того, находится ли диапазон в одном node или несколько node?  Спасибо....

Ответ 1

Я бы предложил использовать метод document или TextRange execCommand, который построен именно для этой цели, но обычно используется в редактируемых документах. Вот ответ, который я дал на аналогичный вопрос:

Следующее должно делать то, что вы хотите. В браузерах, отличных от IE, он включает designMode, применяет цвет фона и затем снова отключает designMode.

UPDATE

Исправлено для работы в IE 9.

ОБНОВЛЕНИЕ 12 сентября 2013 г.

Здесь ссылка, описывающая метод удаления выделенных объектов, созданных этим методом:

fooobar.com/questions/21729/...

function makeEditableAndHighlight(colour) {
    var range, sel = window.getSelection();
    if (sel.rangeCount && sel.getRangeAt) {
        range = sel.getRangeAt(0);
    }
    document.designMode = "on";
    if (range) {
        sel.removeAllRanges();
        sel.addRange(range);
    }
    // Use HiliteColor since some browsers apply BackColor to the whole block
    if (!document.execCommand("HiliteColor", false, colour)) {
        document.execCommand("BackColor", false, colour);
    }
    document.designMode = "off";
}

function highlight(colour) {
    var range;
    if (window.getSelection) {
        // IE9 and non-IE
        try {
            if (!document.execCommand("BackColor", false, colour)) {
                makeEditableAndHighlight(colour);
            }
        } catch (ex) {
            makeEditableAndHighlight(colour)
        }
    } else if (document.selection && document.selection.createRange) {
        // IE <= 8 case
        range = document.selection.createRange();
        range.execCommand("BackColor", false, colour);
    }
}

Ответ 2

Rangy - это библиотека кросс-браузера и библиотека выбора, которая идеально решает эту проблему с помощью CSS Class Applier module. Я использую его для реализации подсветки в различных настольных браузерах и iPad, и он отлично работает.

Tim Down ответ велик, но Rangy избавляет вас от необходимости писать и поддерживать весь этот код обнаружения функции.

Ответ 4

Можете ли вы попробовать добавить класс для окружающего диапазона и применить иерархический CSS?

var span = document.createElement("span");
span.className="selection";
rangeObject.surroundContents(span);

В определении CSS

span.selection, span.selection * {
   background-color : yellow;  
}

Я не пробовал. Но просто угадать, что это сработает.