Как выделить текст объекта Range DOM? - PullRequest
15 голосов
/ 06 апреля 2010

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

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

Теперь я хочу выделить весь текст, который попадает под диапазон объекта. Я делаю это так,

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

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

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

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

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

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

Ответы [ 4 ]

25 голосов
/ 06 апреля 2010

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

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

UPDATE

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

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

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

https://stackoverflow.com/a/8106283/96100

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);
    }
}
4 голосов
/ 09 октября 2012

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

Ответ Тима Дауна великолепен, но Рэнги избавляет вас от необходимости самостоятельно писать и поддерживать весь этот код обнаружения функций.

1 голос
/ 06 апреля 2010

Не могли бы вы уточнить необходимость этой функции. Если вы хотите изменить только стиль выделения выделенного текста, вы можете использовать CSS: ':: selection'

Подробнее: http://www.quirksmode.org/css/selection.html https://developer.mozilla.org/en/CSS/::selection

0 голосов
/ 06 апреля 2010

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...