Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как вставить текст под курсором, исчерпывающий ответ 
:(
    Опции темы
Sardar
Дата 27.11.2004, 18:58 (ссылка) |    (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



 Вопрос: Как вставить текст под курсором.

Столкнулся сегодня с этой задачей, решил ответить на него один раз с рабочим кодом. Надеюсь больше этот вопрос не всплывёт smile

В разных браузерах по разному можно узнать где находится каретка в текстовом поле. Точнее только в Мозилле на данный момент есть возможность узнать положение каретки опрашивая поля:
  • selectionStart -  начало селекции, в символах
  • selectionEnd - конец селекции, в символах
Таким образом можно разбить содержимое на подстроки: до селекции, селекция, после селекции.

В ИЕ есть полезный обьект document.selection который может достать нам обьект DOM'овский обьект(ну почти DOM'овский smile ) TextRange. Изменяя этот обьект мы изменяем содержимое селекции.
Селекция здесь в самом широком смысле! То есть мы можем таким же образом работать над всем содержимым страницы.

В Опере код работать не будет, по старинке текст добавляется в конец.

Следующая сложность это не потерять селекцию(положение курсора) при клике на внешний элемент. Будем отлавливать события потери фокуса, клика и т.д., записывать "позицию курсора" и использовать её когда нужно.
В моём коде есть потенциальная ошибка: если отселектировать текст, затем кликнуть где нибудь по странице, а затем по кнопке вставляющей новый текст, то он будет вставлен в записанную позицию, что не совсем верно - селекция должна исчезнуть если кликаем не по кнопке. Решается отловом событий на body и сбросом записанной селекции, но это по вкусу smile

Код с коментариями:
Код
/**
* Обьект через который мы и будем работать с текстовыми полями.
* Содержит все необходимые поля, легко расширяем по вкусу =)
* @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;}
}

..........
//Пример использования
//эта строка отработает после загрузки страницы.
onload=function(){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
 Оценить мои качества можно тут.
PM   Вверх
Alx
Дата 28.11.2004, 01:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ajaxy
****


Профиль
Группа: Комодератор
Сообщений: 2903
Регистрация: 26.11.2003
Где: Cutopia

Репутация: нет
Всего: 78



аааааааа
Sardar ты монстр! господи, я и не представлял, что эти чёртовы разные браузеры могут делать из одной простой функции в ИЕ такую туеву хучу всякого кода! smile

Это сообщение отредактировал(а) Aliance - 24.3.2005, 01:15


--------------------
PM MAIL WWW ICQ   Вверх
Sardar
Дата 28.11.2004, 02:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Кода на самом деле не много(подсветка убила форматирование), просто возможности чуть шире smile
Забываем о текстовом поле, создаем обьект и работаем с созданным обьектом.
Смотри пример, запусти.

Это сообщение отредактировал(а) Aliance - 24.3.2005, 01:15


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Black
Дата 17.12.2004, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Web-Development
**


Профиль
Группа: Участник
Сообщений: 980
Регистрация: 15.8.2004

Репутация: 2
Всего: 45



ALEXANDRO
где Сардар подвел итог я не нашел зато сделал что хотел :-)

набо было то всего:


Код

<script>
// определяем позицию курсора
var xxx = parent.frames['xxx'].document.forms["xxx"].elements['xxx'];
selStart=xxx.selectionStart;
selEnd=xxx.selectionEnd;
scrTop=xxx.scrollTop;
// дальше некоторый код и затем
// ставим курсор после кода смайлика
    xxx.selectionStart=selStart +code.length;
    xxx.selectionEnd= xxx.selectionStart;
    xxx.scrollTop= scrTop;
    parent.frames['xxx'].document.forms['xxx'].elements['xxx'].focus(); //ставим курсор
</script>


вот что я хотел smile


--------------------
Могу все, но ничего не умею :-)
PM WWW   Вверх
Sardar
Дата 18.12.2004, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



PHP-DIRECTOR если не понял, значит удалять ничего не буду...

Поделим мир на 3 части:
  • те кто пользуется Opera - безнадёжные парни, им никогда не увидеть сей радости
  • те кто пользуется Мозиллоподобными - используется немного примитивный подход, мы задаём для текстового поля начало и конец селекции. Курсор это тоже селекция, где начало и конец в одной точке.
  • те кто пользуется ИЕ - используется немного навороченный способ, управление через обьект selection.
Как видим реально узнать позицию курсора можно только в Мозилле. В IE можно отрасировать текст перед селекцией и узнать позицию, но нам это не нужно, мы просто вставляем в селекцию текст, который и встанет на место курсора.

Также нужно запоминать позицию курсора при потере фокуса, ведь если ты кликнешь на кнопку, то фокус с текстового поля уйдёт smile

Разбирай мой код, там сразу станет ясно smile
Как его использовать:
Код
//пусть у нас есть некоторое текстовое поле
<textarea id="my_text_pole"></textarea>
.....
var txtpole=document.getElementyById("my_text_pole");
//воспользуемся моимкодом, что бу просто работать с этим полем
var hTextarea = new TextAreaSelectionHelper(txtpole);

//допустим этой фунцкией мы будем вставлять смайлики(что угодно) под курсором
function vstav_smajl_pod_kursorom(smile) {
hTextarea.setSelectedText(smile);
}
//а вот этой фунцкией мы будем оборачивать отселектированный текст в заданные теги
function oberni_v_teg_pod_kursorom(tagOpen, tagClose) {
 hTextarea.setSelectedText(tagOpen, tagClose);
}

//как видишь всё ясно :)

<span onclick="vstav_smajl_pod_kursorom(':)')">:)</span><br>
<span onclick="oberni_v_teg_pod_kursorom('[sometag]', '[/sometag]')">Обернуть в [sometag]</span>



--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Aliance
Дата 24.3.2005, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 6
Всего: 137



Sardar
Огромное спасибо за данный код, это просто бестцеллер :-)
6 с половиной баллов smile
PM MAIL WWW ICQ Skype   Вверх
Sardar
Дата 24.3.2005, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Aliance на логе по аське можно создать небольшой мануал, а то вижу народу не ясно smile
Скинь ссылки на примеры что наверстали, будет интересно. А вообще надо смотреть исходник в новом дизайне, там многие фичи включая эту используются. Ждём когда его введут smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Aliance
Дата 24.3.2005, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 6
Всего: 137



Не хотел радовать преждевременно, но завтра (точнее уже сегодня, но после ночи) я как раз собирался выложить готовый пример, с комментариями. без лишнего мусора.
PM MAIL WWW ICQ Skype   Вверх
sergejzr
Дата 24.3.2005, 03:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: нет
Всего: 360



Новая Опера включена?


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Sardar
Дата 24.3.2005, 03:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Опера вроде бы обьект selection поддерживает, следовательно должно работать, если они от поведения ИЕ не отклонялись. В любом случае надо потестить.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Aliance
Дата 24.3.2005, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 6
Всего: 137



PM MAIL WWW ICQ Skype   Вверх
sergejzr
Дата 24.3.2005, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: нет
Всего: 360



Блин! Эта Опера опять выделывается...

Код

http://files.vingrad.ru/Aliance/bbcode.html
Event thread: click
Error:
name: TypeError
message: Statement on line 107: object required
Backtrace:
  Line 107 of inline#1 script in http://files.vingrad.ru/Aliance/bbcode.html
    if (this.iesel && this.iesel.parentElement() == this.target)
    else
      Line 209 of inline#1 script in http://files.vingrad.ru/Aliance/bbcode.html
    post.setSelectedText(tag1, tag2);
  Line 1 of  script 
    wrapTags("[b]", "[/b]");
  At unknown location
    [statement source code not available]

У меня к сож времени нету разбираться smile


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Sardar
Дата 24.3.2005, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 16
Всего: 317



Очень странно, как будто TextRange.parentElement не поддерживается... Поставлю у себя этого зверя, пофиксю, в новом скине этот код применяется... ведь обещали нормальную поддержку... На opera.com последняай документация на версию 7, о 8 только реклама...


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
sergejzr
Дата 31.3.2005, 03:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: нет
Всего: 360



Я перенял твой код и у меня с ним Опера работает... smile
http://www.iwi-iuk.org:8081/tex/index.php




--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Aliance
Дата 1.4.2005, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 6
Всего: 137



А функция «Быстрой цитаты» работает по этому же коду/принципу?

PM MAIL WWW ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Здесь публикуют скрипты, которые уже проверены в обсуждениях других тем (при этом полезно поставить ссылки на все смежные обсуждения) или переносятся кем-либо из модераторов по просьбе участников, если видно, что в результате обсуждения темы был написан полезный или интересный скрипт. Третий возможный вариант - участник форума публикует скрипт, заведомо известный как полезный и эффективный, для, возможно, небольшой доработки и обсуждения.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Наши скрипты | Следующая тема »


 




[ Время генерации скрипта: 0.1642 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.