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

6

Мне нужно получить выбранную пользователем область текстовой области, а затем вставить<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)
}

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

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

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

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

поддерживаяlastFocusedElement переменная может помочь. Найти текст в этом конкретном элементе. Jashwant
Я ожидаю, что замена строки даст вам возможность «заменить все» или «заменить первое вхождение». Если вы используете «первое вхождение» и можете начать с начальной точки выбора, этого может быть достаточно? pjmorse

Ваш Ответ

2   ответа
5

Ты можешь использовать мой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);
это последняя версия, которую нужно включить (+1 в любом случае)? Code.google.com / р / rangyinputs / загрузки / ... dynamic
@ llnk: Да. Есть копия на GitHub для сайта плагинов jQuery, но мне не нужно было ее обновлять. Tim Down
Я проверяю это, и оно работает довольно хорошо. Но я считаю, что ему не хватает функции: когда вы добавляете теги во второй раз, он не удаляет предыдущий добавленный тег. Он вставляет два раза этот тег. Можно ли добавить такое поведение, когда вы используете его два раза с одинаковыми тегами? dynamic
@ llnk: это было бы ненужным беспорядком в плагине. Если у вас есть смещение символов в выделении, тогда достаточно просто манипулировать строками, чтобы проверить наличие тегов, прежде чем добавлять новые теги. Tim Down
2

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

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 код изменен с эта ссылка.

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

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

Похожие вопросы