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

Поиск:

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


Бегун
****


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

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



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

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

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

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

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

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

Код с коментариями:
Код
/**
* Обьект через который мы и будем работать с текстовыми полями.
* Содержит все необходимые поля, легко расширяем по вкусу =)
* @argument  obj  HTMLElment  - текстовое поле, с кторым предстоит работать

* Author: Sardar <Sardar@vingrad.ru>
*/
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 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6984
Регистрация: 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 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6984
Регистрация: 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 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6984
Регистрация: 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


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

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



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


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6984
Регистрация: 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


Профиль
Группа: Админ
Сообщений: 13281
Регистрация: 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 IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Sardar
Дата 24.3.2005, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6984
Регистрация: 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


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

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



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


PM 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   Вверх
sergejzr
Дата 1.4.2005, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


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

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



С ие и мозиллой он всегда работал. проблема только с Оперой
Цитата(Aliance @ 1.4.2005, 17:42)
А функция «Быстрой цитаты» работает по этому же коду/принципу?

Нет, когда сделали сперва, то всем ужастно не понравилось, что цитата в курсор вставлялась. Было очень неудобно.

Добавлено @ 18:57
http://forum.vingrad.ru/index.php?showtopic=32152&hl=
Где то здесь обсуждали smile
PM IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Aliance
Дата 1.4.2005, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


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

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



Цитата(sergej @ 1.4.2005, 18:52)
когда сделали сперва

А как тогда сейчас? Впринципе, различие там только в том, чтобы только отселектрированный текст вставлять...
PM MAIL WWW ICQ Skype   Вверх
sergejzr
Дата 1.4.2005, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


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

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



Value+=цитата smile
PM IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Sardar
Дата 1.4.2005, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


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

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



sergej.z, а я цитату в новом дизайне под курсором вставляю, нужно исправить...


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


I ♥ <script>
****


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

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



Цитата(sergej @ 1.4.2005, 19:11)
Value+=цитата

А чего так? =/
PM MAIL WWW ICQ Skype   Вверх
sergejzr
Дата 1.4.2005, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


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

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



Цитата(Aliance @ 1.4.2005, 20:07)
А чего так? =/

Вот, нашёл smile
http://forum.vingrad.ru/index.php?showtopi...58&unread=1&hl=
Цитата(Sardar @ 1.4.2005, 19:41)
sergej.z, а я цитату в новом дизайне под курсором вставляю, нужно исправить...

Как видишь...

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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 5.10.2004

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



Что-то я не смог разобраться с установкой примера, предложенного Sardar'ом, под IE 6. В JavaScript я разбираюсь плохо, поэтому не смог проанализировать код. Как мне кажется, не записывается позиция курсора - вставка у меня осуществляется в конец текста. Возможно я что-то не так сделал, тогда, пожалуйста, подскажите - что?

Файл HTML:
Код

<script src="insert.js"></script>
<textarea id="textarea1" cols=80 rows=20>hhj</textarea>
<span onClick="test()">Test</span>


Файл "insert.js":
Код

/**
* Обьект через который мы и будем работать с текстовыми полями.
* Содержит все необходимые поля, легко расширяем по вкусу =)
* @argument  obj  HTMLElment  - текстовое поле с кторым предстоит работать

* Author: Sardar <Sardar@vingrad.ru>
*/
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;}
}

//Пример использования
function test() {
var text=new TextAreaSelectionHelper(document.getElementById("textarea1"));
text.setSelectedText("[test]","[/test]");
//text.setSelectedText("[test]");
}

PM MAIL WWW   Вверх
Aliance
Дата 15.8.2005, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


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

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



Код

<script src="insert.js"></script>
...
<textarea id="textarea1" cols=80 rows=20 name="AAAA">hhj</textarea>
<script type="text/javascript">var post=new TextAreaSelectionHelper(document.getElementById("AAAA"));</script>

PM MAIL WWW ICQ Skype   Вверх
-NIK-
Дата 4.11.2005, 12:28 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











эм, я очень слаб в JavaScript, это только для IE? Если да, то имхо есть вариант легче.

Код

<script>
function zzz()  {
  obj_ta=document.form.textarea;
  obj_ta.focus();
  var sel=document.selection;
  var rng=sel.createRange();
  rng.colapse;
  var podst="<b>"+rng.text+"</b>";
  rng.text=podst;
 }
</script>
<form name=form>
<input type=button value=" B " onClick=zzz()><br><br>
<textarea name=textarea cols=50 rows=10></textarea>
</form>


А готового кода для Мазиллы нет? Мне очень нужно, самому разобраться не получается. Помогите пожалуйста!

  Вверх
sergejzr
Дата 4.11.2005, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


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

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



-NIK-, Sardar "только для ИЕ" не пишет smile
PM IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Aliance
Дата 4.11.2005, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


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

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




Модератор: Сообщение скрыто.

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


Ajaxy
****


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

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



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


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


Un salsero
Group Icon


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

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



Цитата(Alx @ 21.1.2006, 14:57 Найти цитируемый пост)

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

Именно так. В версии 1.5 возможно кое что и изменилось. Например document.selection теперь обьектом стал. Но это надо ещё посотреть что, да как. Пока некогда..
PM IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Alx
Дата 21.1.2006, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ajaxy
****


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

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



ок, спасибо.
решений для других браузеров, кроме IE и Firefox так и нету, да?


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


Un salsero
Group Icon


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

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



решение Сардара работает н всём, кроме оперы <8.0 (для старых опер решения нет. программисты там - пофигисты smile)
PM IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
3,14
Дата 11.4.2006, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1614
Регистрация: 18.6.2004
Где: Н. Новгород

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



У меня не работает в IE (пишет object doesn't support this property or method), если выделение текста в textarea сделать двойным кликом.
IE Version: 6.0.2900.2180.xpsp_sp2_gdr.050301-1519


--------------------
Может быть, это только мой бред,
Может быть, жизнь не так хороша,
Может быть, я не выйду на свет,
Но я летал, когда пела душа...
PM MAIL   Вверх
SANCHOS
Дата 19.5.2006, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



А чем вам не нравится более простой вариант для этого действия?

Код

<html>
<head>
<style>
a {text-decoration: underline; color: #0000FF; font-size: 14pt;}
</style>
</head>
<body>
<form name="form">
<INPUT TYPE="text" NAME="tb">
</form>
<a onclick="document.form.tb.value += 'text1' ">text1</a>
<a onclick="document.form.tb.value += 'text2' ">text2</a>
<a onclick="document.form.tb.value += 'text3' ">text3</a>
</body>
</html>


text1,tex2,text3 можно заменять чем угодно. 
PM MAIL   Вверх
godsgame
Дата 3.9.2006, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



ммм.. потратил много времени пытаясь подключить эти ф-ции... Сначала получал ошибку Object not defined/expected или что-то в этом роде... потом решил для начала просто подключить файл..

Получил ошибку: Syntax Error on line 94

подключаю так:
Код

<script LANGUAGE="JavaScript" src='myjs.js'></SCRIPT>


файл:
Код

/**
* Обьект через который мы и будем работать с текстовыми полями.
* Содержит все необходимые поля, легко расширяем по вкусу =)
* @argument  obj  HTMLElment  - текстовое поле, с кторым предстоит работать

* Author: Sardar <Sardar@vingrad.ru>
*/
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("myText"));}

function test() {
 text.setSelectedText("[test]","[/test]");
// text.setSelectedText("[test]");
}


Я даже закоментил ОНЛОАД... но и это не помогло.
Помогите пожалуйста разобраться... ЧЯто-то мне подсказывает что у меня руки кривые.
PM MAIL   Вверх
godsgame
Дата 3.9.2006, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



нашел ответ тут:
Код

http://forum.vingrad.ru/index.php?showtopic=55935&st=15


спасибо Ciber SLasH !
PM MAIL   Вверх
GZep
Дата 11.2.2007, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


участник Винграда
***


Профиль
Группа: Завсегдатай
Сообщений: 1528
Регистрация: 7.7.2006
Где: Москва

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



Sardar, ваш вариант немного не верен...

Вот кусок вашего кода:
Код

  if(document.selection) {//84 строка

Тогда как вместо него надо:
Код

    if (document.selection && document.selection.createRange) {//IE 4.0 (win32) & Opera >= 8.0

Все дело в том, что mac версия ИЕ поддерживает document.selection, но не поддерживает document.selection.createRange smile .
Вот так вот. smile 

Теперь попрошу кого-нибудь помочь мне со своим кодом: (пример Sardar'a мне не подходит)
Собственно, что не работает:
Все прекрасно работает кроме изменения позиции курсора в ИЕ(у меня стоит 7-я финальная версия)...
С остальными браузерами все просто отлично. smile 

Вот код(прямо копируйте и вставляйте в файл для запуска, форма, кнопки и т.д. уже имеются):
Код

<script language="JavaScript" type="text/javascript">
<!--
function InsertTag(id, open, close) {
    var target = document.getElementById(id);
    if (!window.opera)//Даем фокус, если браузер не Opera
        target.focus();
    if (typeof(cursor) != "undefined") {//IE 4.0 (win32) & Opera 8.0
        //alert("IE & Opera");
        //Определяем, есть ли выделение(нам это надо сделать еще до кода встаки тега, иначе будет всегда true
        var haveSel = cursor.text.length ? true : false;
        //Если имеется выделенный участок строки - ставим курсор в конец
        //Иначе - между тегами
        
        //Собственное обводим выделенное тегами
        cursor.text = open + cursor.text + close;
        
        //Работаем с позицией курсора:
        
        if (haveSel) {//Ставим курсор в конец
            cursor.collapse(true);               
        } else {//Ставим курсор между тегами
            //Это тут я нахимичить пытался, вроде все правильно делал, но все-равно ничего не вышло
            //cursor.moveEnd("character", -close.length);
            //cursor.moveStart("character", -target.value.length);
            //cursor.move("character", -4);//target.value.length);            
        }
        cursor.select();//Честно говоря не совсем понимаю зачем эта строчка :)
    }
function PositionSaver(target) {
    if (document.selection && document.selection.createRange) {//IE 4.0 (win32) & Opera 8.0
        cursor = document.selection.createRange().duplicate();
        //cursor = target.createTextRange().duplicate();
        return;
    }
}
// -->
</script>
<form>
    <textarea
        onselect='PositionSaver(this);'
        onclick='PositionSaver(this);'
        onkeyup='PositionSaver(this);'
        onfocus='PositionSaver(this);'
        id="area"
        cols="100"
        rows="20">
    </textarea>
</form>
<a href="javascript:InsertTag('area', '', '');">[b]</a><br />
<a href="javascript:InsertTag('area', '[i]', '[/i]');">[i]</a>

Помогите пожалуйста! Не знаю, почему этот ие не хочет никак курсор двигать, ни в какую...  smile 

Это сообщение отредактировал(а) GZep - 11.2.2007, 21:56


--------------------
user posted imageuser posted image
PM MAIL WWW ICQ Skype GTalk   Вверх
Sardar
Дата 12.2.2007, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


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

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



Цитата(GZep @  11.2.2007,  20:55 Найти цитируемый пост)
Sardar, ваш вариант немного не верен...

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

Коллапсировать селекцию это прировнять начало к концу или конец к началу, смотря какое направление. Следовательно если передвинуть конец и сколлапсировать селекцию, то передвинем курсор куда нужно. В твоём случае двигаем только если текста в селекции не было, следовательно достаточно только cursor.moveEnd("character", -close.length);.

Цитата(GZep @  11.2.2007,  20:55 Найти цитируемый пост)
cursor.select();//Честно говоря не совсем понимаю зачем эта строчка smile

На одном поле может быть масса селекций, это такие хендлеры по тексту, помогающие изменять его в некотором месте. Селекция на экране это нечто другое, она обычно одна. Вызовом .select() мы переносим селекцию на экране под конкретную селекцию в скрипте. Короче что бы курсор реально передвинулся smile


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


участник Винграда
***


Профиль
Группа: Завсегдатай
Сообщений: 1528
Регистрация: 7.7.2006
Где: Москва

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



Цитата(Sardar @  12.2.2007,  00:28 Найти цитируемый пост)
только cursor.moveEnd

А cursor.moveStart в моем случае можно не вставлять? Это потому что отсутствует выделение, а имеется только позиция курсора?

А как тогда поставить курсор в ие в самый конец строки? Не выделенной части а всей строки целиком... smile 

Цитата(Sardar @  12.2.2007,  00:28 Найти цитируемый пост)
Вызовом .select() мы переносим селекцию на экране под конкретную селекцию в скрипте

Эта такая особенность в ие?

А вот еще проблема появилась:
Код

//кусок кода
        alert(cursor.text.length);//выводит количество выделенных символов
        cursor.text = open + cursor.text + close;
        alert(cursor.text.length);//всегда почему-то выводит "0"

Почему так?

Это сообщение отредактировал(а) GZep - 12.2.2007, 17:26


--------------------
user posted imageuser posted image
PM MAIL WWW ICQ Skype GTalk   Вверх
Sardar
Дата 12.2.2007, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


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

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



Цитата(GZep @  12.2.2007,  15:25 Найти цитируемый пост)
А cursor.moveStart в моем случае можно не вставлять? Это потому что отсутствует выделение, а имеется только позиция курсора?

Если не нужно ставить курсор, то не нужно, но тогда и .select() убери. "Курсор" == селекция с нулевой длинной.

Цитата(GZep @  12.2.2007,  15:25 Найти цитируемый пост)
А как тогда поставить курсор в ие в самый конец строки? Не выделенной части а всей строки целиком... 

Читай абзац выше. Отселектировать всё что нужно, сколлапсировать в начало или в конец. Можно и move(End|Start) использовать. Только не забудь .select() на конце, что бы реальная селекция на экране изменилась.

Цитата(GZep @  12.2.2007,  15:25 Найти цитируемый пост)
Эта такая особенность в ие?

Нет, это спецификация selection.

Цитата(GZep @  12.2.2007,  15:25 Найти цитируемый пост)
Почему так?

Потому что после установки текста селекция всегда коллапсируется. Сделай с неё дубликат, он по моему не должен изменяться. Хотя у ИЕ с дубликатами глюки есть, можно двигать концы одной селекции, а дубликат "магическим способом" тоже будет изменяться. Больше на эту тему в основном разделе о indent'aх в питоне, фича к форумскому полю ответа по ctrl+[].


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


участник Винграда
***


Профиль
Группа: Завсегдатай
Сообщений: 1528
Регистрация: 7.7.2006
Где: Москва

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



Цитата(Sardar @  12.2.2007,  17:54 Найти цитируемый пост)
Можно и move(End|Start)

Вот я как раз это и применял, только толку без  .select() не было. Вот в этом, наверное, и была вся проблема.

Цитата(Sardar @  12.2.2007,  17:54 Найти цитируемый пост)
спецификация selection.

Вот я там был smile Только я там думал нормальных примеров найти и уже их использовать...

Цитата(Sardar @  12.2.2007,  17:54 Найти цитируемый пост)
Потому что после установки текста селекция всегда коллапсируется. Сделай с неё дубликат, он по моему не должен изменяться. Хотя у ИЕ с дубликатами глюки есть, можно двигать концы одной селекции, а дубликат "магическим способом" тоже будет изменяться. Больше на эту тему в основном разделе о indent'aх в питоне, фича к форумскому полю ответа по ctrl+[]

Спасибо, буду копать, думаю, скоро разберусь и выложу тут как сделать.

Sardar, Даже не знаю, что сказать. Такая помощь! Да чтобы я без Вас делал! smile 

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

Это сообщение отредактировал(а) GZep - 12.2.2007, 20:13


--------------------
user posted imageuser posted image
PM MAIL WWW ICQ Skype GTalk   Вверх
GZep
Дата 13.2.2007, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


участник Винграда
***


Профиль
Группа: Завсегдатай
Сообщений: 1528
Регистрация: 7.7.2006
Где: Москва

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



Цитата(Sardar @  12.2.2007,  17:54 Найти цитируемый пост)
Можно и move(End|Start) использовать

Sardar, помогите, пожалуйста, не работает.
Вот пример использования:
[только_что_вставленный_тег][текст][/только_что_вставленный_тег][курсор] - все правильно, мне так и надо!
[только_что_вставленный_тег][текст][/только_что_вставленный_тег][курсор][предыдущий_тег][текст][/предыдущий_тег] - нет, мне надо, чтобы курсор в самом конце стоял!

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

Вот что нахимичил...:
Код

        if (haveSel) {//"Сварачиваем" выделение и ставим курсор в конец
            //cursor.collapse(true);
            //alert("haveSel");
            //cursor.expand("textedit");
            cursor.setEndPoint("EndToEnd", cursor);
            //alert(cursor.compareEndPoints("EndToEnd", target));
            //cursor.move("character", end);
            cursor.move("textedit", end);
        //move(End|Start)
        //move("character",0)
        }
        cursor.select();

Это только кусок, естественно, кода.


--------------------
user posted imageuser posted image
PM MAIL WWW ICQ Skype GTalk   Вверх
Sardar
Дата 14.2.2007, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


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

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



Не знаю зачем ставить курсор всегда в конец поля, но можно просто отселектировать всё содержимое и коллапсировать селекцию в конец. 
Обернуть поле в селекцию можно методом .moveToElementText.


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


участник Винграда
***


Профиль
Группа: Завсегдатай
Сообщений: 1528
Регистрация: 7.7.2006
Где: Москва

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



Вот так, вроде, должно работать, но опять smile 
Код

    if (typeof(cursor) != "undefined") {//IE 4.0 (win32) & Opera 8.0
            cursor.text = open + cursor.text + close;//Обводим выделенное тегами
            //Работаем с позицией курсора:
            //cursor.collapse(true);
            //cursor.expand("textedit");
            //cursor.setEndPoint("EndToEnd", cursor);
            //alert(cursor.compareEndPoints("EndToEnd", target));
            cursor.moveToElementText(target);
            //cursor.moveEnd("character", -close.length);
            cursor.move("character", end);//"Сварачиваем" выделение и ставим курсор в конец
            //cursor.move("textedit", end);
            //move(End|Start)//move("character",0)
        cursor.select();//Переносим селекцию
        return;//Завершаем работу функции.
    }

Просто на самом деле уже интересно: получится так сделать или нет. smile 
Sardar, посмотрите, пожалуйста, что там не так?


--------------------
user posted imageuser posted image
PM MAIL WWW ICQ Skype GTalk   Вверх
Sardar
Дата 17.2.2007, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


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

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



Цитата(GZep @  17.2.2007,  20:34 Найти цитируемый пост)
cursor.move("character", end);//"Сварачиваем" выделение и ставим курсор в конец

Это вообще откуда? Как end вычислил? И вообще зачем, если ты уже отселектировал всё. Я сказал коллапсировать, т.е. .collapse(true)


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


участник Винграда
***


Профиль
Группа: Завсегдатай
Сообщений: 1528
Регистрация: 7.7.2006
Где: Москва

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



Sardar, спасибо, получилось smile 
Описание кода:
  • Если имеется выделенный участок, то он обводится тегами, а курсор ставиться в самый конец, для дальнейшего набора текста.
  • Если браузер не поддерживает выделение, то в конец добавляется один "открывающий" тег или парный ему "закрывающий", если уже есть "открывающий" тег.
  • Прадусматривается mac версия ИЕ, где не поддерживается объект document.selection.createRange
  • Предусматривается отмена передачи фокуса если браузер - Opera
  • Поддержка нескольких форм ввода
Вот код. Форма воода имеется, можно прямо сохранять и тестить. О багах пишите в эту тему.
Код

<script language="JavaScript" type="text/javascript">
<!--
InsertTag_tags = new Array();//Массив, необходимый для стрых браузеров, которые не поддерживают выделение
function InsertTag(id, open, close) {
    var target = document.getElementById(id);
    if (!window.opera)//Даем фокус, если браузер не Opera
        target.focus();
    if (typeof(cursor) != "undefined") {//IE 4.0 (win32) & Opera 8.0
        //alert("IE & Opera");
        if (cursor.text.length) {//Если имеется выделение
            cursor.text = open + cursor.text + close;//Обводим выделенное тегами
            cursor.moveToElementText(target);//Расширяем облость селекции на всё поле ввода
            cursor.collapse(false);//"Сварачиваем" выделение в курсор и ставим его в конец
        } else {//Если имеется курсор без выделенного участка строки
            cursor.text = open + close;//Вставляем теги на место курсора
            cursor.moveEnd("character", -close.length);//Ставим курсор между тегами
        }
        cursor.select();//Переносим селекцию
        return;//Завершаем работу функции.
    }
    if (typeof(cursorStart) != "undefined") {//Gecko
        var start = target.value.substring(0, cursorStart),//Получаем строку, находящуюся до выделения
            selected = target.value.substring(cursorStart, cursorEnd),//Получаем выделенную строку (или пустую строку, если ничего не выделено)
            end = target.value.substr(cursorEnd);//Получаем строку, находящуюся после выделения
        target.value = start + open + selected + close + end;//Изменяем значение объекта
        target.selectionStart = target.selectionEnd = selected.length ? target.value.length : start.length + open.length;//Устанавливаем позицию курсора
        target.scrollTop = cursorScroll;//Задаем scroll
        return;//Завершаем работу функции.
    }
    if (InsertTag_tags[open + close]) {//Если в глобальном массиве есть ключ с именем тека - добавляем вторую часть тега
        target.value += close;
        InsertTag_tags[open + close] = false;
    } else {//Если в глобальном массиве нету ключа с именем тега или этот ключ имеет значение false - добавляем в конец значения объекта первую часть тега
        target.value += open;
        InsertTag_tags[open + close] = true;
    }
}
function PositionSaver(target) {
    if (document.selection && document.selection.createRange) {//IE 4.0 (win32) & Opera 8.0
        cursor = document.selection.createRange().duplicate();
        return;
    }
    if (typeof(target.selectionStart) != "undefined") {//FireFox & Mozilla
        cursorStart = target.selectionStart;
        cursorEnd = target.selectionEnd;
        cursorScroll = target.scrollTop;
        return;
    }
}
// -->
</script>
<form>
    <textarea
        onselect='PositionSaver(this);'
        onclick='PositionSaver(this);'
        onkeyup='PositionSaver(this);'
        onfocus='PositionSaver(this);'
        id="area"
        cols="100"
        rows="20">
</textarea></form><br />
<a href="javascript:InsertTag('area', '', '');">[b]</a><br />
<a href="javascript:InsertTag('area', '[i]', '[/i]');">[i]</a><br />

Sardar, посмотрите, пожалуйста, кроссбраузерный ли этот код?

Это сообщение отредактировал(а) GZep - 18.2.2007, 12:51


--------------------
user posted imageuser posted image
PM MAIL WWW ICQ Skype GTalk   Вверх
Sardar
Дата 18.2.2007, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


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

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



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



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


Шустрый
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 24.7.2007
Где: Москва

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



Получается замечательно, но переход курсора в конец текста не всегда удобен - лучше бы он оставался приблизительно на месте редактирования - только вот никак не придумываетсяЮ как бы это сделать.  smile 
--------------------
С уважением. Rigel. http://www.smoliy.ru
PM MAIL WWW ICQ   Вверх
gridis
Дата 9.2.2008, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Sardar, здравствуйте, у меня такой к Вам вопрос....
Мне вашь пример очень понравился.... только у меня такая проблема.... мне нужна вставка HTML кода под курсором... в опере и файрфоксе  я нормально вставляю через EditField.execCommand('inserthtml',false, "");

ИЕ такой функции нет..... 
PM MAIL   Вверх
Sardar
Дата 10.2.2008, 02:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


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

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



Получили селекцию, меняем содержимое через .pasteHTML(html)


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


Новичок



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

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



спасибо за код. вопрос: а что делать если надо вставить текст под курсором. не ЗАМЕНИТЬ отселектированный текст, а как-то запомнить позицию курсора. в фф это можно а как быть с ИЕ?

Это сообщение отредактировал(а) introtel - 1.6.2009, 15:03
PM MAIL   Вверх
GogElf
Дата 17.7.2009, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Сам я не местный  smile но хочу внести вклад.
Я не очень много понимаю в javascript (ну на стадии что-то сломать). Меня очень напрягает писать id и по ним чтоб код работал.  smile 
В общем кому хочется сделать 1 панельку с кнопками на 2-3 или более полей то заменяем:
Код

onload=function(){text=new TextAreaSelectionHelper(document.getElementById("textarea"));}

на
Код

function poz(names){
    text=new TextAreaSelectionHelper(names);
}

И вписываем onclick
Код

<textarea cols="80" rows="10" onclick="return poz(this)"></textarea>

 smile 

Это сообщение отредактировал(а) GogElf - 17.7.2009, 01:50
PM MAIL   Вверх
maxipub
Дата 31.3.2011, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Тема прикреплена... она еще жива?

Заметил странный баг в оригинальном скрипте. FF 3.6.13

Код

<script>
/**
* Обьект через который мы и будем работать с текстовыми полями.
* Содержит все необходимые поля, легко расширяем по вкусу =)
* @argument  obj  HTMLElment  - текстовое поле, с кторым предстоит работать

* Author: Sardar <Sardar@vingrad.ru>
*/
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]");
}
</script>

<textarea id="textarea" cols=80 rows=20>0 qwerty asdfgh zxcvbn
1 qwerty asdfgh zxcvbn
2 qwerty asdfgh zxcvbn
3 qwerty asdfgh zxcvbn
4 qwerty asdfgh zxcvbn
5 qwerty asdfgh zxcvbn
6 qwerty asdfgh zxcvbn
7 qwerty asdfgh zxcvbn
8 qwerty asdfgh zxcvbn
9 qwerty asdfgh zxcvbn</textarea>
<span onClick="test()">Test</span>


Оригинальный код, просто с прописанными данными для textarea.

Если выделить мышкой несколько строк, но так, чтоб одна из строк была выделена не полностью, например:

Код

4 qwerty asdfgh zxcvbn
5 qwerty asdfgh zxcvbn
6 qwerty asdfgh


После клика по "Test" будет выполнена некорректная ставка.

При выделении мышкой в FF у меня все корректно работает только если выделена лишь часть одной строки, либо несколько строк, но полностью.

В общем, очень жаль, наработка вроде ничего, но работает почему-то некорректно. Судя по всему, что-то с обработкой событий.

ЗЫ: вот и в IE 8 тоже нашел небольшой баг, но это еще терпимо. К примеру, выделяем строки:

Код

3 qwerty asdfgh zxcvbn
4 qwerty asdfgh zxcvbn
5 qwerty asdfgh zxcvbn
6 qwerty asdfgh zxcvbn
7 qwerty asdfgh zxcvbn


После клика по "Test" будет выполнена корректная ставка, но с некорректным выделением (что выделяется - указано жирным):

[test]3 qwerty asdfgh zxcvbn
4 qwerty asdfgh zxcvbn
5 qwerty asdfgh zxcvbn
6 qwerty asdfgh zxcvbn
7 qwerty asdfgh zxcvbn
[/test]

Т.е. он начало выделения смещает на минус (количество переводов в выделенной строке - 1).

Как убрать эти баги? Особенно первый. Или подскажите альтернативу. Сам писал-писал, не вышло. Другие варианты смотрел - не подходят.

Необходимо чтоб после вставки текста под курсор, texarea всегда подскролливался к курсору (к месту вставки).

Только чтоб без лишних библиотек и наворотов. Обычная же вещь, с чего сложности?

Заранее благодарю!
PM MAIL   Вверх
maxipub
Дата 31.3.2011, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Если не понятно о чем речь, могу снять видео и выложить чтоб быстрее было.

Кстати, тут на форуме прогеров (хе-хе smile) данная функция тоже не совсем чисто работает. Но то что тут - это уже мелочи. Вообще как на vBulletin сделано - идеал. По крайней мере, так и не нашел к чему докопаться. Другое дело, что что тут, что там - js-ы все шифрованные, собаки.
PM MAIL   Вверх
TsibaSasha
Дата 6.3.2012, 03:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Tsyba



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

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



Браво smile 
Уважаю, столько сил и терпения надо иметь, что бы написать такой код для форума)
PM MAIL WWW   Вверх
Sanchezzz
Дата 17.9.2012, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

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



Предлагаю свое решение с использованием плагина caret
Пощупать можно тут накидал демку 




--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
Google
  Дата 24.11.2017, 14:03 (ссылка)  





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


 




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


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

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