Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Доработка функции tag() - возврат позиции курсора.
 
 автор: DJ Paltus   (07.04.2009 в 10:43)   письмо автору
 
 

Для внедрения ББкодов слямзил из этого форума функцию tag().
Она клёвая, но при обработке длинных текстов мешает одно: после вставки ББкода уходит фокус с поля ввода.
Фокус вернуть получилось, но курсор становится в конец текста, и место правки приходится искать заново. Как запомнить координаты курсора и воткнуть его на место при возврате фокуса?


  function tag(text1, text2)
  {
     if ((document.selection))
     {
       document.form.content.focus();
       document.form.document.selection.createRange().text = text1+document.form.document.selection.createRange().text+text2;
     } else if(document.forms['form'].elements['content'].selectionStart != undefined) {
         var element    = document.forms['form'].elements['content'];
         var str     = element.value;
         var start    = element.selectionStart;
         var length    = element.selectionEnd - element.selectionStart;
         element.value = str.substr(0, start) + text1 + str.substr(start, length) + text2 + str.substr(start + length);
     } else document.form.content.value += text1+text2;
       document.form.content.focus(); //вот я его вернул

  }

  Ответить  
 
 автор: PAT   (07.04.2009 в 14:10)   письмо автору
 
   для: DJ Paltus   (07.04.2009 в 10:43)
 

Функция tag () на этом форуме немного "левая".
Авторы скрипта, видимо, забыли о том, что свойства selectionStart и selectionEnd можно не только ЧИТАТЬ, но и можно ИЗМЕНЯТЬ (т.е. эти свойства типа read/write)

Да и вы сами, что очевидно, и не попытались разобраться с кодом, который я вам ЗДЕСЬ уже давал в ответ на аналогичный этому ваш вопрос о вставке табуляции в текстареа - http://www.softtime.ru/forum/read.php?id_forum=4&id_theme=63453
Что очень грустно. Пишешь для людей, полагая, что они ЗАИНТЕРЕСУЮТСЯ и РАЗБЕРУТСЯ в написанном... а они, как ПОПКИ, просто передирают, совершенно ни о чём не задумываясь :-(((

Сходите по ссылке и посмотрите на код.
ПЕРЕД вставкой там сохраняется значение позиции старта выделения
var w = selectionStart;

А после вставки эта позиция изменяется (вместе с позицией конца выделения)
selectionStart = selectionEnd = ++w; 
на всего один символ (ибо всего один символ \t и вводился). И в том моём скрипте курсор у вас никуда не девался, а ВСЕГДА находился ПОСЛЕ вставленного символа табуляции. И никакого фокуса я в текстареа не возвращал (ибо текстареа и так изначально в фокусе).

Можно было бы в том скрипте курсор ВСЕГДА оставлять ПЕРЕД вставленным символом табуляции. Догадались - КАК? Правильно, надо просто НЕ МЕНЯТЬ значение переменной w
selectionStart = selectionEnd = w; //плюсики убраны

В "слямзенной" вами на этом форуме функции ничем этим товарищи не озаботились

В общем, вам нужен или ПОСЛЕДНИЙ КОД (если курсор вам нужен В НАЧАЛЕ ВСТАВКИ), или же надо к переменной w добавить длину изначально выделеного фрагмента + количество символов вставляемых BB-кодов - тогда курсор будет ПОСЛЕ ВСТАВКИ. (соответственно, не забудьте сначала сохранить стартовую позицию - см. ПЕРВЫЙ КОД в этом ответе).
А если вы РАЗНЕСЁТЕ начало и конец, то ВСЯ ВСТАВКА у вас ВЫДЕЛИТСЯ:
selectionStart = w; selectionEnd = w + ДЛИНА_ВСТАВКИ_И_BB-кодов;


И никакого второго document.form.content.focus(); //вот я его вернул в функции просто НЕ НУЖНО.

  Ответить  
 
 автор: DJ Paltus   (07.04.2009 в 14:50)   письмо автору
 
   для: PAT   (07.04.2009 в 14:10)
 

Ну что ж, поделом мне! ))
Критику воспринял, код исправил:

  function tag(text1, text2)
  {
     if ((document.selection))
     {
       document.form.content.focus();
       document.form.document.selection.createRange().text = text1+document.form.document.selection.createRange().text+text2;
     } else if(document.forms['form'].elements['content'].selectionStart != undefined) {
         var element    = document.forms['form'].elements['content'];
         var str     = element.value;
         var start    = element.selectionStart;
         var length    = element.selectionEnd - element.selectionStart;
         element.value = str.substr(0, start) + text1 + str.substr(start, length) + text2 + str.substr(start + length);
     } else document.form.content.value += text1+text2;
            document.form.content.focus();
     element.selectionStart = element.selectionEnd = start;
  }

Строку про фокус ("вот я его вернул") пришлось оставить, так как при тыкании в кнопку вставки на странице, фокус все же уходит, в отличие от случая использования горячих клавиш..

Но (предчувствую град негодования) осталась еще одна штука. Когда текста в поле "текстареа" много, он, после вставки, прокручивается на начало. Это не очень плохо, так как одно нажатие стрелок и всё опять на экране, но есть ли возможность фокусироваться сразу на курсоре?

  Ответить  
 
 автор: PAT   (07.04.2009 в 18:36)   письмо автору
 
   для: DJ Paltus   (07.04.2009 в 14:50)
 

>Критику воспринял, код исправил

Вообще-то код вы как раз ИСПОРТИЛИ.
Запустите его в MSIE и сразу это увидите.
Строку element.selectionStart = element.selectionEnd = start; надо было помещать не в самый
конец функции, а в конец инструкции только для Мозиллы (т.е. перед закрывающей фигурной
скобкой условия else if(document.forms['form'].elements['content'].selectionStart != undefined)


>Строку про фокус ("вот я его вернул") пришлось оставить, так как при тыкании в кнопку вставки на
странице, фокус все же уходит


Видимо, вы очень плохой человек, раз даже фокус от вас уходит.
От меня вот он НИКУДА не уходит.
Что на кнопку нажимай, что на ссылку.
Да, в MSIE курсор в текстареа ПОСЛЕ ВСТАВКИ не мерцает. Но он ТАМ ЕСТЬ. [Как в анекдоте -
"Суслика видишь? Нет. А он есть!"]
А в Mozilla он не только есть, но и "подмигивает".
Ведь сами пишете, что "одно нажатие стрелок и всё опять на экране"


>есть ли возможность фокусироваться сразу на курсоре?

Разумеется, есть. Во-первых, в MSIE и так "всё стоит на месте" ПОСЛЕ вставки.
Ну а для Mozilla в этом деле поможет sсrollLeft и scrollTop.

В общем, держите код и со ссылкой, и с кнопочкой.
А также с домашним заданием:
<script>
function tag (obj, pre, after)
{
if (document.selection)
   with (document.selection.createRange ()) {text = pre + text + after}   
else if (obj.selectionStart)
   with (obj)
      {
      var t = scrollTop, l = scrollLeft, txt = obj.value,
      st = selectionStart, ln = selectionEnd - st; focus ();
      value = txt.substr (0, st) + pre + txt.substr (st, ln) + after + txt.substr (st + ln);
      selectionStart = selectionEnd = st; scrollTop = t; scrollLeft = l;
      }
else
   obj.value += pre + after;

</script>

<textarea wrap="off" id="txa" rows="10" cols="40"></textarea>
<hr>
<table cellpadding="0" cellspacing="0"><tr>
<th style="padding:0 6px">
<a href=#" onclick="tag (document.getElementById ('txa'), '{b}', '{/b}'); return false">[ b ][ /b ]</a></th>
<th style="padding:0 6px">
<input type="button" value="[ i ] [ /i ]" onclick="tag (document.getElementById ('txa'), '{i}', '{/i}')"></th></tr>
<tr><th>Ctrl+B</th><td align="center"><i>Ctrl+I</i></td></tr>
</table>

Надписи внизу увидели?
Совместите теперь этот код с кодом, что я вам давал раньше (для TAB'a) и сделайте, чтобы можно
было BB-коды вставлять "горячими клавишами", никаких ссылочек/кнопочек не нажимая.
Справитесь?
Или только и можете, что "предчувствовать град негодования"? :-))

PS. BB-коды немного видоизменены, чтобы здесь они правильно отразились. У себя на компе фигурные скобки замените на квадратные
PS2. перенос выключен (wrap="off") для наглядности. Можете убрать, если к таковому виду текстареа непривыкШИ :-)

  Ответить  
 
 автор: DJ Paltus   (07.04.2009 в 21:36)   письмо автору
2.6 Кб
 
   для: PAT   (07.04.2009 в 18:36)
 

Суров! ))
В аттаче решение.
Одного не смог постичь - почему в "Мозилле", если выделение происходит с самого начала поля, ББкод вставляется в самый конец, игнорируя выделенный диапазон.

  Ответить  
 
 автор: PAT   (07.04.2009 в 22:47)   письмо автору
 
   для: DJ Paltus   (07.04.2009 в 21:36)
 

Можно было бы и не ошибаться (почему scrollLeft = 0)
Можно было бы оформить и покрасивше, например, так:
<script>
function tag (x, y, z)
{
if (document.selection)
   with (document.selection.createRange ()) {text = y + text + z}
else if (x.selectionStart >= 0) with (x)
   {
   var u = scrollTop, v = scrollLeft, t = value,
   s = selectionStart, l = selectionEnd - s; focus ();
   value = t.substr (0, s) + y + t.substr (s, l) + z + t.substr (s + l);
   selectionStart = selectionEnd = s, scrollTop = u, scrollLeft = v;
   }
else x.value += y + z; x.focus ();
}

function myFunc (y)
{
var z = true, y = window.event || y, x = y.target || y.srcElement,
w = {'66' : 'b}', '85' : 'u}', '73' : 'i}'};
if (y.ctrlKey && w [y.keyCode])
   {z = false; tag (document.getElementById ('txa'), '{' + w [y.keyCode], '{/' + w [y.keyCode])}
return z;
}
</script>

<div style="display: inline">
<img src="i/sys_bold.gif"      onclick="tag (document.getElementById ('txa'), '{b}', '{/b}')" width="18" height="18" alt="Жирный CTRL+B"       title="Жирный CTRL+B"      >
<img src="i/sys_italic.gif"    onclick="tag (document.getElementById ('txa'), '{i}', '{/i}')" width="18" height="18" alt="Курсив CTRL+I"       title="Курсив CTRL+I"      >
<img src="i/sys_underline.gif" onclick="tag (document.getElementById ('txa'), '{u}', '{/u}')" width="18" height="18" alt="Подчеркнутый CTRL+U" title="Подчеркнутый CTRL+U">
</div><br>

<textarea wrap="off" id="txa" rows="10" cols="40" onkeydown="return myFunc (event)"></textarea>


Но в целом - МОЛОДЕЦ! :-)

Поизучайте, сравните...

И несколько замечаний:
1. протокол javascript: НИГДЕ, кроме атрибута HREF ссылки не пишется.
Но и даже в HREF его использовать не надо. В общем, ЗАБУДЬТЕ о нём НАВСЕГДА!
2. зачем нужны ссылки для картинок? Ведь они и сами поддерживают onclick
3. возврат фокуса для MSIE действительно нужен. Ибо вы писали здесь про "кнопочки", а у вас,
оказывается, "картиночки". А теги <IMG> в MSIE отдают фокус очень плохо.


>почему в "Мозилле", если выделение происходит с самого начала поля, ББкод вставляется в
самый конец, игнорируя выделенный диапазон


Да потому что при выделении с самого начала selectionStart равняется НУЛЮ, и условие
if (x.selectionStart) возвращает false. Я исправил - посмотрите.


Ишь, каку красивую фиговину совместными усилиями сотворили...
А вы - "слямзить" :-((

  Ответить  
 
 автор: DJ Paltus   (08.04.2009 в 00:46)   письмо автору
7.9 Кб
 
   для: PAT   (07.04.2009 в 22:47)
 

Я немножко против последней оптимизации кода, так как вставляю у себя не ББкоды, а обычные тэги, периодически с параметрами, и чтобы поддерживать их номенклатуру в гибком состоянии, проще использовать старый модульный вид, имхо. В аттаче - то, что сегодня было решено вынести в тулбар. Это в лучшем случае 2/3 от будущего количества.
Приведенному коду пришлось в ИЕшном случае добавить (угадайте что?) фокус:
if (document.selection){
obj.focus();
with (document.selection.createRange ()) {text = pre + text + after}
}

потому что без него ишак таки уходил по клику фокусироваться на картинку, если не выбран текст в окошке и писал всё перед картинками.
И я отказался от идеи упрощать имена переменных до икс-игрека, потому что тяжко ориентироваться с непривычки в незнакомом языке.

И большое Вам спасибо. Языку я, конечно, не научился и на йоту, но работу продолжать уже можно.
Не прощаюсь, так как на очереди у меня через пару недель аякс взамен фреймов в CMS.)))

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования