Вопрос: Как вставить текст под курсором.Столкнулся сегодня с этой задачей, решил ответить на него один раз с рабочим кодом. Надеюсь больше этот вопрос не всплывёт  В разных браузерах по разному можно узнать где находится каретка в текстовом поле. Точнее только в Мозилле на данный момент есть возможность узнать положение каретки опрашивая поля: - selectionStart - начало селекции, в символах
- selectionEnd - конец селекции, в символах
Таким образом можно разбить содержимое на подстроки: до селекции, селекция, после селекции. В ИЕ есть полезный обьект document.selection который может достать нам обьект DOM'овский обьект(ну почти DOM'овский  ) TextRange. Изменяя этот обьект мы изменяем содержимое селекции. Селекция здесь в самом широком смысле! То есть мы можем таким же образом работать над всем содержимым страницы. В Опере код работать не будет, по старинке текст добавляется в конец. Следующая сложность это не потерять селекцию(положение курсора) при клике на внешний элемент. Будем отлавливать события потери фокуса, клика и т.д., записывать "позицию курсора" и использовать её когда нужно. В моём коде есть потенциальная ошибка: если отселектировать текст, затем кликнуть где нибудь по странице, а затем по кнопке вставляющей новый текст, то он будет вставлен в записанную позицию, что не совсем верно - селекция должна исчезнуть если кликаем не по кнопке. Решается отловом событий на body и сбросом записанной селекции, но это по вкусу  Код с коментариями: Код | /** * Обьект через который мы и будем работать с текстовыми полями. * Содержит все необходимые поля, легко расширяем по вкусу =) * @argument obj HTMLElment - текстовое поле с кторым предстоит работать * * Author: Sardar <[email protected]> */ function TextAreaSelectionHelper(obj) { this.target=obj; this.target.carretHandler=this; //ссылка самого на себя для текстового поля /** * Помним что события могут быть уже опредлеенны, тогда нужно использовать * очереди. Конечно реализация для ИЕ и Мозиллы в корне различаются, почитать * и достать готовый код можно здесь: http://forum.vingrad.ru/index.php?showtopic=32350 */ 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): ""; } /** * Вставить код под курсором. Если текст не отселектирован(не фокуса) и * позиция не взята, то вставить в конец текстового поля. * * @argument text String - заменить селекцию на этот текст * @argument secondtag String - если задан, то селекция не заменяется, а обрамляется этими тегами */ TextAreaSelectionHelper.prototype.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; } } /** * Это функции для веса =) */ TextAreaSelectionHelper.prototype.getText=function() { return this.target.value; } TextAreaSelectionHelper.prototype.setText=function(text) { this.target.value=text; } /** * Приватная фукнкция, записывающая позицию курсора */ 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;} }
.......... //Пример использования var text=new TextAreaSelectionHelper(document.getElementById("textarea")); function test() { text.setSelectedText("[test]","[/test]"); // text.setSelectedText("[test]"); } <textarea id="textarea" cols=80 rows=20></textarea> <span onClick="test()">Test</span>
|
--------------------
Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут.
|