Справочники, инструменты, документация

JavaScript: Обернуть выделенный текст тегами в textarea

С помощью JavaScript свойств selectionStart и selectionEnd можно сделать оборачивание выделенного текста тегами или BB-кодами.

Без jquery

<script>
  function addedidor(tag, tagEnd) {
    tagEnd = tagEnd || tag.replace(/\s.*/, '');
    var obj = document.querySelector('.textarea');
    if (document.selection) obj.value += "<" + tag + "></" + tagEnd + ">";
    else if (typeof (obj.selectionStart) == "number") {
      var start = obj.selectionStart;
      var end = obj.selectionEnd;
      var value = obj.value;
      obj.select();
      if (start != end) {
        obj.value = value.substr(0, start) + "<" + tag + ">" + value.substr(start, end - start) + "</" +
          tagEnd + ">" + value.substr(end);
        obj.setSelectionRange(start, end + tag.length + tagEnd.length + 5);
      } else {
        obj.value = value.substr(0, start) + "<" + tag + "></" + tagEnd + ">" + value.substr(start);
        obj.setSelectionRange(start + tag.length + 2, start + tag.length + 2);
      }
    }
  }
</script>

<input type="button" value='<font color="red"></font>' onClick='addedidor("font color=\"red\"");'>
<input type="button" value='<font color=""></font>' onClick='addedidor("font color=\"\"");'>
<input type="button" value='<a href=""></a>' onClick='addedidor("a href=\"\"");'>
<input type="button" value="<b>" onClick="addedidor('b');">
<input type="button" value="<i>" onClick="addedidor('i');">
<input type="button" value="<u>" onClick="addedidor('u');">
<input type="button" value="<h2>" onClick="addedidor('h2');">
<input type="button" value="<h3>" onClick="addedidor('h3');">
<input type="button" value="абзац" onClick="addedidor('p');">
<input type="button" value="ссылка" onClick="addedidor('a');">

<textarea class="textarea"></textarea>

Пример:

Рассмотрим добавление тега <b> с помощью jquery

<a id="button-b" href="#"><b>Жирный</b></a>
<textarea id="control" rows="5">...</textarea>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$('#button-b').click(function(){
    var control = $('#control')[0];
    var start = control.selectionStart;
    var end = control.selectionEnd;

    if (start != end) {
        var text = $(control).val();
        $(control).val(text.substring(0, start) + '<b>' + text.substring(start, end) + '</b>' + text.substring(end));

        // Ставим каретку в конец добавленного тега
        $(control).focus();
        var sel = end + 7;
        control.setSelectionRange(sel, sel);
    }
    return false;
});
</script>

Чтобы не дублировать код для других тегов, лучше написать отдельную функцию:

<a id="button-b" href="#"><b>Жирный</b></a>
<a id="button-i" href="#"><i>Курсив</i></a>
<a id="button-u" href="#"><u>Подчеркнутый</u></a>
<a id="button-s" href="#"><strike>Зачеркнутый</strike></a>
<a id="button-a" href="#">Ссылка</a>

<textarea id="control" rows="5">...</textarea>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
function addTag(open, close) {
    var control = $('#control')[0];
    var start = control.selectionStart;
    var end = control.selectionEnd;
    if (start != end) {
        var text = $(control).val();
        $(control).val(text.substring(0, start) + open + text.substring(start, end) + close + text.substring(end));
        $(control).focus();
        var sel = end + (open + close).length;
        control.setSelectionRange(sel, sel);
    }
    return false;
}

// Жирный
$('#button-b').click(function(){
    return addTag('<b>', '</b>');
});

// Курсив
$('#button-i').click(function(){
    return addTag('<i>', '</i>');
});

// Подчеркнутый
$('#button-u').click(function(){
    return addTag('<u>', '</u>');
});

// Зачеркнутый
$('#button-s').click(function(){
    return addTag('<strike>', '</strike>');
});

// Ссылка
$('#button-a').click(function(){
    return addTag('<a href="' + prompt('Введите адрес', '') + '">', '</a>');
});

// При клике на кнопки не снимаем фокус с textarea
$('a').on('mousedown', function() {
    return false;
});
</script>