JavaScript скрипты
Обрамление выделенного текста тегами
Определимся с терминолигией.
Текстовыми полями формы будем считать textarea и input type="text".
Выделением в этих полях будем считать установленный фокус или участок текста в случае, когда выделено несколько символов.
Необходимо написать JavaScript-сценарий, умеющий:
- запоминать пользовательское выделение
- обрамлять выделение с обеих сторон любыми текстовыми данными, например тегами.
- не терять выделение после обрамления.
JavaScript скрипт
// >>> За основу взят объект, написанный автором Sardar <[email protected]> // Массив экземпляров объекта var textAreaSelectionObjects = []; // Получаем экземпляр объекта function getTextAreaSelection(id) { if (typeof(textAreaSelectionObjects[id]) == "undefined") { textAreaSelectionObjects[id] = new textAreaSelectionHelper(id); } return textAreaSelectionObjects[id]; } // Конструктор, принимает в качестве аргумента ID текстарии function textAreaSelectionHelper(id) { var obj = document.getElementById(id); this.target = obj; // Создаем свойства carretHandler для доступа к объекту в контексте узла // из обработчиков событий this.target.carretHandler = this; // Добавляем обработчик событий this.target.onchange = _textareaSaver; this.target.onclick = _textareaSaver; this.target.onkeyup = _textareaSaver; this.target.onfocus = _textareaSaver; if(!document.selection) this.target.onSelect = _textareaSaver; // Свойства для запоминания позиции выделения this.start=-1; this.end=-1; this.scroll=-1; this.iesel=null; } // В прототип записываем методы textAreaSelectionHelper.prototype = { // Получим выделение getSelectedText : function() { return this.iesel? this.iesel.text: (this.start>=0&&this.end>this.start)? this.target.value.substring(this.start,this.end): ""; }, // Установим текстовые фрагменты до выделения - text // и после него, если нужно - secondtag setSelectedText : function(text, secondtag) { if (this.iesel) { if (typeof(secondtag) == "string") { var l = this.iesel.text.length; this.iesel.text = text + this.iesel.text + secondtag; this.iesel.moveEnd("character", -secondtag.length); this.iesel.moveStart("character", -l); } else { this.iesel.text = text; } this.iesel.select(); } else if (this.start >= 0 && this.end >= this.start) { var left = this.target.value.substring(0, this.start); var right = this.target.value.substr(this.end); var scont = this.target.value.substring(this.start, this.end); if (typeof(secondtag) == "string") { this.target.value = left + text + scont + secondtag + right; this.end = this.target.selectionEnd=this.start+text.length+scont.length; this.start = this.target.selectionStart = this.start + text.length; } else { this.target.value = left + text + right; this.end = this.target.selectionEnd = this.start + text.length; this.start = this.target.selectionStart = this.start + text.length; } this.target.scrollTop = this.scroll; this.target.focus(); } else { this.target.value += text + ((typeof(secondtag) == "string") ? secondtag: ""); if (this.scroll >= 0) this.target.scrollTop = this.scroll; } }, } // Обработчик событий. Занимается сохранением информации о выделении и позиции скролла function _textareaSaver() { if(document.selection) { this.carretHandler.iesel = document.selection.createRange().duplicate(); } else if(typeof(this.selectionStart) != "undefined") { this.carretHandler.start = this.selectionStart; this.carretHandler.end = this.selectionEnd; this.carretHandler.scroll = this.scrollTop; } else { this.carretHandler.start = this.carretHandler.end = -1; } } // Клиентские функции, хотя можно обойтись и без них function setBold(id) { // Жирность getTextAreaSelection(id).setSelectedText('<b>', '</b>'); } function setItalic(id) { // Курсив getTextAreaSelection(id).setSelectedText('<i>', '</i>'); } function setUnderline(id) { // Подчеркивание getTextAreaSelection(id).setSelectedText('<u>', '</u>'); }
Код HTML
<h1>Вставка тегов для текстарии</h1>
<input type="button" value="B" class="bold" onclick="setBold('textareaId');">
<input type="button" value="I" class="ital" onclick="setItalic('textareaId');">
<input type="button" value="U" class="under" onclick="setUnderline('textareaId');">
<textarea id="textareaId"></textarea>
<h1>Вставка тегов для текстового инпута</h1>
<input type="button" value="B" class="bold" onclick="setBold('inputId');">
<input type="button" value="I" class="ital" onclick="setItalic('inputId');">
<input type="button" value="U" class="under" onclick="setUnderline('inputId');">
<input type="text" id="inputId" value="">
// Инициализируем объекты, чтобы сразу отслеживать выделения
getTextAreaSelection('textareaId');
getTextAreaSelection('inputId');