Поставить теги вокруг выделенного пользователем текста?

Мне нужно получить выбранную пользователем область текстовой области, а затем вставить<a> метит вокруг него.

Я использую это, чтобы получить выбранную пользователем область:

var textComponent = document.getElementById('article');
var selectedText;

if (document.selection != undefined)
{
    textComponent.focus();
    var sel = document.selection.createRange();
    selectedText = sel.text;
}

// Mozilla version
else if (textComponent.selectionStart != undefined)
{
    var startPos = textComponent.selectionStart;
    var endPos = textComponent.selectionEnd;
    selectedText = textComponent.value.substring(startPos, endPos)
}

Теперь я знаю, что могу выполнить поиск строки для выбранного пользователем текста и вставить вокруг него теги, но что произойдет, если выбранный пользователем текст появится в тексте, например, дважды.

Привет тебе, до свидания.

Если пользователь выделяет второе «вы» для ссылки, которую он хочет, несомненно, замена строки будет помещать теги вокруг каждого экземпляра «вы».

Какой лучший способ сделать это?

 Jashwant24 мая 2012 г., 16:01
поддерживаяlastFocusedElement переменная может помочь. Найти текст в этом конкретном элементе.
 pjmorse24 мая 2012 г., 15:49
Я ожидаю, что замена строки даст вам возможность «заменить все» или «заменить первое вхождение». Если вы используете «первое вхождение» и можете начать с начальной точки выбора, этого может быть достаточно?

Ответы на вопрос(2)

Решение Вопроса

Ты можешь использовать мойjQuery плагин за это Демо):

$("#article").surroundSelectedText('<a href="foo.html">', "</a>");

В качестве альтернативы вы можете использоватьgetInputSelection()ункция @, которую я несколько раз выкладывал в Stack Overflow, чтобы получить начальные и конечные индексы выбора во всех основных браузерах, а затем выполнить подстановку строк в текстовой областиvalue:

var sel = getInputSelection(textComponent);
var val = textComponent.value;
textComponent.value = val.slice(0, sel.start) +
                      '<a href="foo.html">' +
                      val.slice(sel.start, sel.end) +
                      "</a>" +
                      val.slice(sel.end);
 dynamic05 мар. 2013 г., 14:16
это последняя версия, которую нужно включить (+1 в любом случае)? Code.google.com / р / rangyinputs / загрузки / ...
 Tim Down05 мар. 2013 г., 16:25
@ llnk: Да. Есть копия на GitHub для сайта плагинов jQuery, но мне не нужно было ее обновлять.
 dynamic06 мар. 2013 г., 01:52
Я проверяю это, и оно работает довольно хорошо. Но я считаю, что ему не хватает функции: когда вы добавляете теги во второй раз, он не удаляет предыдущий добавленный тег. Он вставляет два раза этот тег. Можно ли добавить такое поведение, когда вы используете его два раза с одинаковыми тегами?
 Tim Down06 мар. 2013 г., 18:20
@ llnk: это было бы ненужным беспорядком в плагине. Если у вас есть смещение символов в выделении, тогда достаточно просто манипулировать строками, чтобы проверить наличие тегов, прежде чем добавлять новые теги.

что вы действительно хотите, это начальные / конечные позиции для добавления тегов.

var textComponent = document.getElementById('article');
var selectedText;
var startPos;
var endPos;

// the easy way
if (textComponent.selectionStart != undefined)
{
    startPos = textComponent.selectionStart;
    endPos = textComponent.selectionEnd;
}
// the hard way
else if (document.selection != undefined)
{
    textComponent.focus();
    var sel = document.selection.createRange();
    var range = document.selection.createRange();
    var stored_range = range.duplicate();
    stored_range.moveToElementText(textComponent);
    stored_range.setEndPoint( 'EndToEnd', range );
    startPos = stored_range.text.length - range.text.length;
    endPos = startPos + range.text.length;
} 

// add in tags at startPos and endPos
var val = textComponent.value;
textComponent.value = val.substring(0, startPos) + "<a>" + val.substring(startPos, endPos) + "</a>" + val.substring(endPos);

IE код изменен с эта ссылка.

РЕДАКТИРОВАТЬ Обратите внимание на комментарий Тима Дауна о новых строках. Кроме того, возможно, используйте его решение, потому что это лучше.

 Tim Down24 мая 2012 г., 16:21
Я бы предпочелselectionStart а такжеselectionEnd над подходом TextRange в браузерах, которые поддерживают оба (например, IE> = 9). Кроме того, этот код не будет правильно определять выборки, начинающиеся или заканчивающиеся пустыми строками в IE: см. Jsfiddle.net / Lq5aP / 1. Наконец, в ветке IE есть опечатка: должно бытьendPos = startPos + range.text.length;.
 apsillers24 мая 2012 г., 16:31
Исправил код и порекомендовал ваше решение, так как это домен, в который вы явно вложили много предыдущих мыслей.
 Tim Down24 мая 2012 г., 16:33
Спасибо, это мило с твоей стороны.

Ваш ответ на вопрос