1с вставить текст в позицию курсора
При написании, просмотре, редактировании кода, навигации по пунктам меню 1С значительно ускорить эти процессы позволяют определенные комбинации нажатия на клавиши, так называемые «Горячие клавиши». Сразу скажу, что перечень будет приведен неполный. Только те, которые я использую в своей работе. Поэтому нелишним будет после прочтения этой статьи обратиться к справке 1С, чтобы расширить этот перечень. Список будет разбит на соответствующие разделы в соответствии с функциональным назначением. В основном будут рассмотрены сочетания, применимые при работе в режиме конфигуратора 1С.
При указании сочетаний клавиш будут использоваться латинские символы, хотя при использовании переключать клавиатуру на английский язык конечно же не нужно. Итак приступим.
Навигация
F12 — если установить курсор на место вызова процедуры или функции, то с помощью этой клавиши можно перейти непосредственно к процедуре или функции;
Ctrl + ] — позволяет из начала логической конструкции перейти в ее конец. Под логическими конструкциями понимаются: Если … КонецЕсли, Для … Цикл … КонецЦикла, Функция … КонецФункции, Процедура … КонецПроцедуры. То есть если курсор у нас спозиционирован на операторе «Если», то после применения данного сочетания, он спозиционируеься на операторе «КонецЕсли». Очень удобно в ситуациях, когда приходится анализировать большие блоки кода;
Ctrl + [ — позволяет из конца логической конструкции переместиться в ее начало;
Ctrl + T — при редактировании кода эта комбинация клавиш позволяет переместиться в дерево метаданных конфигурации и спозиционироваться на том объекте, чей код вы сейчас редактируете;
Alt + F2 — Устанавливает метку на строчке кода (впоследствии можно перемещаться к этой метке). Отображается синим кружком с левой стороны строки. Имя метки не устанавливается. Возможен последовательный обход меток в рамках текущего окна кода;
F2 — Переход к следующей метке по направлению «вперед» в текущем окне кода;
Shift + F2 — Переход к следующей метке по направлению «назад» в текущем окне кода;
Ctrl + F — поиск текста;
F3 — найти следующий фрагмент текста;
Shift + F3 — найти предыдущий фрагмент текста;
Ctrl + Home — переместить курсор в начало текста;
Ctrl + End — переместить курсор в конец текста;
Home — переместить курсор в начало текущей строки;
End — переместить курсор в конец текущей строки;
Ctrl + «стрелка вправо» — переместить курсор на одно слово вправо;
Ctrl + «стрелка влево» — переместить курсор на одно слово влево;
Работа с окнами
Alt + Enter — открыть окно свойств. Информация в окне отображается для того элемента который был выделен до нажатия клавиш. Например, это может быть объект конфигурации, ячейка табличного документа, и т.д.;
Alt + Shift + Enter — открыть окно дополнительных свойств. Используется для просмотра дополнительных свойств объектов конфигурации;
Shift + Ctrl + Т — открывает окно с шаблонами текста;
Редактирование текста
Ctrl + / (на цифровой клавиатуре) — закомментировать выделенный блок текста;
Shift + Ctrl + / (на цифровой клавиатуре) — раскомментировать выделенный блок текста;
Ctrl + C — скопировать выделенный текст в буфер;
Ctrl + V — вставить из буфера;
Ctrl + C — вырезать выделенный текст в буфер;
Выделение текста
Ctrl + A — выделить все;
Shift + Ctrl + Home — выделить текст начиная с текущей позиции курсора и до начала текста;
Shift + Ctrl + End — выделить текст начиная с текущей позиции курсора и до конца текста;
Shift + Home — выделить текст начиная с текущей позиции курсора и до начала строки;
Shift + End — выделить текст начиная с текущей позиции курсора и до конца строки;
Shift + Ctrl + «стрелка вправо» — выделить слово справа от курсора. Удерживая Shift и Ctrl и последовательно нажимая стрелку можно выделять сразу несколько слов;
Shift + Ctrl + «стрелка влево» — выделить слово слева от курсора;
Shift + «стрелка вниз» — выделить строку со смещением курсора на одну строчку вниз. Удобно использовать при выделении нескольких строк;
Shift + «стрелка вверх» — выделить строку со смещением курсора на одну строчку вверх;
Отладка
F7 — обновить конфигурацию;
F5 — обновляет конфигурацию, открывает новое окно в режиме предприятия и включает режим отладки открытого окна;
Ctrl + F5 — открывает новое окно в режиме предприятия и включает режим отладки открытого окна без обновления конфигурации;
F9 — устанавливает точку останова на текущей строке кода в конфигураторе;
Alt + F9 — открывает окно со списком всех точек останова конфигурации. Из этого окна можно переместиться к любой из них;
Ниже приведены сочетания клавиш, которые используются в процессе отладки после того как отработала точка останова
Sift + F9 — открывает окно в котором можно посмотреть значение переменной или результат вычисления какой-либо функции. Переменную или функцию можно предварительно выделить;
F11 — пошаговая отладка. При каждом нажатии выполняется одна строка кода;
Shift + F11 — текущая процедура или функция выполняется до конца, происходит выход из нее и отладочный курсор устанавливается на строке следующей за той из которой эта процедура (функция) вызывалась;
Если вы хотите сделать конструктор формул, вам нужно вставить текст, соответствующий кнопке, в соответствующую позицию текста.Эффект будет следующим:
Возникшие проблемы:
1. Как получить позицию курсора и вставить контент в соответствующую позицию
Две ситуации:
(1) После того, как пользователь щелкнет позицию, вставьте контент в позицию курсора.
(2) После того, как пользователь выберет несколько слов, нажмите кнопку, чтобы заменить текст
Решение:
selectionStart с selectionEnd Может быть получена начальная позиция курсора текущего элемента.
2. Положение меняется при многократной вставке
После написания я обнаружил, что нажатие кнопки может успешно вставить, но если вы продолжите нажимать кнопку, чтобы вставить операцию:
Текст, вставленный в первый раз, будет в позиции курсора. При повторном нажатии кнопки курсор автоматически вернется в начало поля ввода. После нескольких щелчков мыши поле ввода будет удалено из поля ввода.самое началоВставьте это.
В этом случае, если вы добавляете переменную, записывайте позицию последнего щелчка и длину добавленного поля и вставляйте текст в последнюю вставленную позицию каждый раз, когда вы щелкаете. Но таким образом, если пользователь щелкнет в другом месте и хочет вставить текст, он не будет доступен. Это вызывает проблему 3.
3. Компонент использует element-ui, el-button
После того как я заменил кнопку el на div и добавил то же событие щелчка, вышеуказанная проблема не возникла. Явление в это время выглядит следующим образом:
Текст, вставленный в первый раз, будет в позиции курсора. При повторном нажатии кнопки курсор автоматически вернется в конец текста в поле ввода. После нескольких щелчков мыши текст в поле ввода будет удален.В конце концовВставьте это.
Таким образом, это соответствует привычкам использования, но есть еще одна проблема4.
4. Предотвратить выбор элемента (после выбора элемента он будет вести себя как вопрос 2, нерешенный).
После добавления события блокировки оно отображается как вопрос 2.
Я не смотрел исходный код, но метод предотвращения выбора содержимого элемента должен использоваться, когда компонент кнопки был упакован.
Конструктор запроса легко вызывается для строки, содержащей готовый текст запроса. Так работают все консоли запросов. Но задача становится нетривиальной, если у нас есть код не на языке запросов, а на встроенном языке 1С:Предприятия. В нём запрос является лишь частью текста и он представлен не в чистом виде, а в виде строковой константы с переносами строк, двойными кавычками и прочими "неудобствами".
Необходимость задавать исполняемый код в пользовательском режиме появляется не так уж и редко. Для этого создано множество инструментов - универсальные регламентные задания, консоли кода, динамические подписки на события и т.д. С помощью этих инструментов можно создавать код, содержащий запросы, и хорошо бы иметь возможность вызывать для этих запросов конструктор. Более того, во всем известных "Инструментах разработчика" уже есть решение этой задачи для обычных форм с применением библиотеки регулярных выражений (внешней библиотеки, подключаемой как COM-объект).
Мы же рассмотрим решение исключительно средствами 1С, которое вы сможете легко встраивать в свои формы, и которое будет подходить как для обычной, так и для управляемой формы (в толстом клиенте). Следующая иллюстрация показывает, чего мы хотим добиться от нашего алгоритма:
То есть нам необходимо получить возможность работать с запросами в коде аналогичную той, что дает Конфигуратор - открывать существующий запрос, изменять его, и затем возвращать измененный запрос в код на языке 1С с форматированием и сохранением позиции курсора. Эта задача сложна лишь потому, что у поля тестового документа 1С мало методов для работы с текстом и их придется "изобретать" самостоятельно.
Сначала опишем алгоритм на человеческом языке, а затем перейдем к реализации алгоритма на языке платформы.
Нам нужно:
1) Определить позицию курсора в поле текстового документа на форме.
2) Извлечь текст до курсора и после курсора.
3) В тексте, расположенном до курсора, найти открывающую запрос кавычку. В тексте расположенном после курсора найти первую несдвоенную кавычку от начала строки, это будет закрывающая кавычка.
4) Отделить текст запроса, расположенный между открывающей и закрывающей кавычками. А также выделить код, расположенный до начала запроса и после него.
5) Преобразовать код запроса таким образом, чтобы он нормально воспринимался конструктором запроса. Вместо двойных кавычек подставить одинарные, убрать символы вертикальной черты. После чего передать полученный текст в конструктор.
6) После закрытия конструктора сделать обратное преобразование полученного из него кода запроса. Добавить отступы и привести его к виду, который будет нормально воспринят интерпретатором языка 1С.
7) Соединить новый код запроса с текстом, который раньше располагался до и после текста запроса. Загрузить полученный код в поле формы и восстановить позицию курсора.
Теперь перейдем к поэтапной реализации этого алгоритма на языке 1С. Для демонстрации выберем обычную форму. Для управляемой формы код будет отличаться всего несколькими строками, и он также есть в прикрепленном к этой публикации файле. Пусть поле текстового документа на нашей форме имеет имя "Поле".
1) Упростим процесс кодирования введением дополнительных переменных и определим текущую позицию курсора. Позицию курсора запишем в переменные НачалоСтроки и НачалоКолонки. Значение переменной НачалоСтроки в ходе алгорима менять не будем. Оно понадобится в конце для восстановления позиции курсора:
//БЛОК №1 - ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ
ЭлементПоля = ЭлементыФормы . Поле ;
Кавычка = """" ;
ДвойнаяКавычка = """""" ;
ЗаменаДляДвойнойКавычки = Строка (Новый УникальныйИдентификатор );
КоличествоСтрок = ЭлементПоля . КоличествоСтрок ();
НачалоСтроки = 0 ;
НачалоКолонки = 0 ;
КонецСтроки = 0 ;
КонецКолонки = 0 ;
ЭлементПоля . ПолучитьГраницыВыделения ( НачалоСтроки , НачалоКолонки , КонецСтроки , КонецКолонки );
ЭлементПоля . УстановитьГраницыВыделения ( НачалоСтроки , НачалоКолонки , Началостроки , НачалоКолонки );
2) Определим текст, расположенный до курсора и после него. Для этого поле текстового документа дает нам только одну возможность - устанавливать границы выделения и получать выделенный текст. Далее нам придется искать открывающую и закрывающую запрос кавычку. Сильной помехой в этом могут оказаться двойные кавычки. Чтобы избежать лишнего кода по обработке двойных кавычек используем следующий прием. Временно заменим все двойные кавычки на уникальную строку. Обратную замену будем проводить в конце алгоритма, при получении нового кода:
//БЛОК №2 - ОПРЕДЕЛЕНИЕ ТЕКСТА ДО КУРСОРА И ПОСЛЕ КУРСОРА
ЭлементПоля . УстановитьГраницыВыделения ( 1 , 1 , Началостроки , НачалоКолонки );
ТекстДоКурсора = ЭлементПоля . ВыделенныйТекст ;
ЭлементПоля . УстановитьГраницыВыделения ( НачалоСтроки , НачалоКолонки , КоличествоСтрок + 1 , 1 );
ТекстПослеКурсора = ЭлементПоля . ВыделенныйТекст ;
ЭлементПоля . УстановитьГраницыВыделения ( НачалоСтроки , НачалоКолонки , Началостроки , НачалоКолонки );
//гарантируем отсутствие в тексте двойных кавычек
ТекстДоКурсора = СтрЗаменить ( ТекстДоКурсора , ДвойнаяКавычка , ЗаменаДляДвойнойКавычки );
//в тексте после курсора необходимо оставить первую кавычку, если сразу после нее идет двойная
//случай подряд идущих кавычек в количестве более 5-ти штук обрабатывать не будем
ТекстПослеКурсора = СтрЗаменить ( Лев ( ТекстПослеКурсора , 1 ) +
СтрЗаменить ( Сред ( ТекстПослеКурсора , 2 ), ДвойнаяКавычка , ЗаменаДляДвойнойКавычки ), ДвойнаяКавычка , ЗаменаДляДвойнойКавычки ) ;
3) Двигаясь по строке кода, расположенного до курсора, находим открывающую запрос кавычку. Поскольку мы избавились от двойных кавычек, то найти ее несложно. Нужно просто найти кавычку, которая не была закрыта следующей за ней. Правда, нужно учитывать, что кавычки в комментариях надо пропустить, перемещаясь сразу к концу строки, а также то, что курсор сам мог находиться внутри двойной кавычки в строке запроса:
//БЛОК №3 - ИЩЕМ ПОЗИЦИЮ ОТКРВАЮЩЕЙ И ЗАКРЫВАЮЩЕЙ КАВЫЧКИ ДЛЯ СТРОКИ ЗАПРОСА
ПозицияОткрывающейКавычки = 0 ;
ПозицияЗакрывающейКавычки = 0 ;
ВСтроке = Ложь;
КавычкиЕсть = Ложь;
ПозицияПредыдущейКавычки = 0 ;
ПоизцияПоследнейКавычки = 0 ;
Позиция = 1 ;
ДлинаТекстаДоКурсора = СтрДлина ( ТекстДоКурсора );
//ИЩЕМ ОТКРЫВАЮЩУЮ КАВЫЧКУ
Пока Позиция < = ДлинаТекстаДоКурсора Цикл
ТекущийСимвол = Сред ( ТекстДоКурсора , Позиция , 1 );
ПредыдущийСимвол = " " ;
Если Позиция > 1 Тогда
ПредыдущийСимвол = Сред ( ТекстДоКурсора , Позиция - 1 , 1 );
КонецЕсли;
Если ТекущийСимвол = Кавычка Тогда
ВСтроке = НЕ ВСтроке ;
ПозицияПредыдущейКавычки = ПоизцияПоследнейКавычки ;
ПоизцияПоследнейКавычки = Позиция ;
КавычкиЕсть = Истина;
КонецЕсли;
//Обработка комментария - начало
Если НЕ ВСтроке И ПредыдущийСимвол = "/" И ТекущийСимвол = "/" Тогда
//это комментарий, пропускаем символы до конца строки
Пока ТекущийСимвол <> Символы . LF И ТекущийСимвол <> Символы . CR Цикл
Позиция = Позиция + 1 ;
Если Позиция > ДлинаТекстаДоКурсора Тогда
Прервать;
КонецЕсли;
ТекущийСимвол = Сред ( ТекстДоКурсора , Позиция , 1 );
КонецЦикла;
Продолжить;
КонецЕсли;
//Обработка комментария - конец
Позиция = Позиция + 1 ;
КонецЦикла;
//ОСОБЫМ ОБРАЗОМ ОБРАБОТАЕМ СЛУЧАЙ НАХОЖДЕНИЯ КУРСОРА В
//ДВОЙНОЙ КАВЫЧКЕ ВНУТРИ СТРОКИ ЗАПРОСА
Если НЕ ВСтроке И КавычкиЕсть И СтрДлина ( ТекстПослеКурсора ) > 0 Тогда
Если Сред ( ТекстДоКурсора , ДлинаТекстаДоКурсора , 1 ) = Кавычка И Лев ( ТекстПослеКурсора , 1 ) = Кавычка Тогда
ВСтроке = Истина;
ПоизцияПоследнейКавычки = ПозицияПредыдущейКавычки ;
ТекстДоКурсора = Лев ( ТекстДоКурсора , ДлинаТекстаДоКурсора - 1 );
ТекстПослеКурсора = ЗаменаДляДвойнойКавычки + Сред ( ТекстПослеКурсора , 2 );
КонецЕсли;
КонецЕсли;
//ЕСЛИ НАШИЛИ ОТКРЫВАЮЩУЮ КАВЫЧКУ, ТО ИЩЕМ ЗАКРЫВАЮЩУЮ
Если ВСтроке Тогда
ПозицияОткрывающейКавычки = ПоизцияПоследнейКавычки ;
ПозицияЗакрывающейКавычки = Найти ( ТекстПослеКурсора , Кавычка );
КонецЕсли;
4) Теперь можно выделить код между кавычками (запрос) и код расположенный до и после запроса. Чтобы текст запроса был воспринят конструктором его необходимо преобразовать, убрав из начала каждой его строки вертикальную черту:
//БЛОК №4 - ОПРЕДЕЛЯЕМ ТЕКСТ ДО ЗАПРОСА, ТЕКСТ ЗАПРОСА И ТЕКСТ ПОСЛЕ ЗАПРОСА
//ПОСЛЕ ЧЕГО ВОЗРАЩАЕМ ДВОЙНЫЕ КАВЫЧКИ В КОД, НЕ ЯВЛЯЮЩИЙСЯ ЧАСТЬЮ ЗАПРОСА
Конструктор = Новый( "КонструкторЗапроса" );
ГраницыЗапросаНайдены = ПозицияОткрывающейКавычки <> 0 И ПозицияЗакрывающейКавычки <> 0 ;
ТекстДоНачалаЗапроса = Лев ( ТекстДоКурсора , ПозицияОткрывающейКавычки );
ТекстПослеКонцаЗапроса = Сред ( ТекстПослеКурсора , ПозицияЗакрывающейКавычки );
ТекстЗапросаССимвовамиВертикальнойЧерты = Сред ( ТекстДоКурсора , ПозицияОткрывающейКавычки + 1 )
+ Лев ( ТекстПослеКурсора , ПозицияЗакрывающейКавычки - 1 );
//для конструктора запроса вместо двойной кавычки будем подставлять одинарную
ТекстЗапросаССимвовамиВертикальнойЧерты =
СтрЗаменить ( ТекстЗапросаССимвовамиВертикальнойЧерты , ЗаменаДляДвойнойКавычки , Кавычка );
КоличествоСтрокВТексте = СтрЧислоСтрок ( ТекстЗапросаССимвовамиВертикальнойЧерты );
ТекстЗапроса = "" ;
Для К = 1 To КоличествоСтрокВТексте Цикл
СтрокаИзТекстаЗапроса = СокрЛП ( СтрПолучитьСтроку ( ТекстЗапросаССимвовамиВертикальнойЧерты , К ));
Если Лев ( СтрокаИзТекстаЗапроса , 1 ) = "|" Тогда
//для конструктора запроса убираем вертикальную черту в начале строки
СтрокаИзТекстаЗапроса = Сред ( СтрокаИзТекстаЗапроса , 2 );
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + СтрокаИзТекстаЗапроса + Символы . LF ;
КонецЦикла;
Конструктор . Текст = ТекстЗапроса ;
КонецЕсли;
//возвращаем двойные кавычки
ТекстДоНачалаЗапроса = СтрЗаменить ( ТекстДоНачалаЗапроса , ЗаменаДляДвойнойКавычки , ДвойнаяКавычка );
ТекстПослеКонцаЗапроса = СтрЗаменить ( ТекстПослеКонцаЗапроса , ЗаменаДляДвойнойКавычки , ДвойнаяКавычка );
5) Передаем текст запроса в конструктор и, если конструктор отработал успешно, вычисляем отступ, который будем добавлять к строкам запроса. Отступ необходимо добавлять, чтобы код запроса вставился на форму красиво, а не безусловно лепился к левому краю текстового поля:
//БЛОК №5 - ОТКРЫВАЕМ КОНСТРУКТОР ЗАПРОСА С ПОЛУЧЕННОЙ СТРОКОЙ ЗАПРОСА И В СЛУЧАЕ УСПЕШНОГО
//РЕЗУЛЬТАТА ВЫЧИСЛЯЕМ ОТСТУП, КОТОРЫЙ БУДЕМ ДОБАВЛЯТЬ К КАЖДОЙ СТРОКЕ ЗАПРОСА
Если НЕ Конструктор . ОткрытьМодально () Тогда
Возврат;
КонецЕсли;
ТекстЗапроса = Конструктор . Текст ;
Если ПустаяСтрока ( ТекстЗапроса ) Тогда
Возврат;
КонецЕсли;
ДлинаТекстаДоНачалаЗапроса = СтрДлина ( ТекстДоНачалаЗапроса );
Позиция = ДлинаТекстаДоНачалаЗапроса - 1 ;
Пока Позиция >= 1 Цикл
Если Сред ( ТекстДоНачалаЗапроса , Позиция , 1 ) = Символы . LF Тогда
Прервать;
КонецЕсли;
Позиция = Позиция - 1 ;
КонецЦикла;
СтрокаОтступа = Сред ( ТекстДоНачалаЗапроса , Позиция + 1 , ДлинаТекстаДоНачалаЗапроса - Позиция - 1 );
ДлинаСтрокиОтступа = СтрДлина ( СтрокаОтступа );
СтрокаОтступаИзПробеловИТабуляций = "" ;
Для К = 1 To ДлинаСтрокиОтступа Цикл
Если Сред ( СтрокаОтступа , К , 1 ) = Символы . Tab Тогда
СтрокаОтступаИзПробеловИТабуляций = СтрокаОтступаИзПробеловИТабуляций + Символы . Tab ;
Иначе
СтрокаОтступаИзПробеловИТабуляций = СтрокаОтступаИзПробеловИТабуляций + " " ;
КонецЕсли;
КонецЦикла;
6) Теперь у нас есть текст запроса на языке запросов. Нужно преобразовать его в строку на встроенном языке 1С. Добавляем символы вертикальной черты и отступы, преобразуем одинарные кавычки в двойные:
//БЛОК №6 - ОБРАБАТЫВАЕМ РЕЗУЛЬТАТ, ЗАМЕНЯЕМ ОДИНАРНЫЕ КАВЫЧКИ НА ДВОЙНЫЕ,
//ДОБАВЛЯЕМ ОТСТУП И ВЕРТИКАЛЬНУЮ ЧЕРТУ СТРОКАМ ЗАПРОСА НАЧИНАЯ СО ВТОРОЙ
ТекстЗапроса = СтрЗаменить ( ТекстЗапроса , Кавычка , ДвойнаяКавычка );
КоличествоСтрокВТексте = СтрЧислоСтрок ( ТекстЗапроса );
ТекстЗапросаССимвовамиВертикальнойЧерты = СтрПолучитьСтроку ( ТекстЗапроса , 1 );
Для К = 2 To КоличествоСтрокВТексте Цикл
ТекстЗапросаССимвовамиВертикальнойЧерты = ТекстЗапросаССимвовамиВертикальнойЧерты +
Символы . LF + СтрокаОтступаИзПробеловИТабуляций + "|" + СтрПолучитьСтроку ( ТекстЗапроса , К );
КонецЦикла;
7) Задача фактически решена. Склеиваем код, располагавшийся до запроса, новую строку запроса и код, располагавшийся после запроса. Загружаем получившуюся строку в поле формы и восстанавливаем позицию курсора:
//ЗАГРУЖАЕМ НОВЫЙ КОД В ТЕКСТОВОЕ ПОЛЕ И УСТАНАВЛИВАЕМ КУРСОР НА ПРЕЖНЮЮ ПОЗИЦИЮ
ИтоговыйКод = ТекстДоНачалаЗапроса + ТекстЗапросаССимвовамиВертикальнойЧерты + ТекстПослеКонцаЗапроса ;
ЭлементПоля . УстановитьТекст ( ИтоговыйКод );
НоваяКолонка = СтрДлина ( СтрокаОтступаИзПробеловИТабуляций )+ 2 ;
ЭлементПоля . УстановитьГраницыВыделения ( НачалоСтроки , НоваяКолонка , НачалоСтроки , НоваяКолонка );
ЭтаФорма . ТекущийЭлемент = ЭлементПоля ;
Для применения этого метода в своих разработках вам достаточно заменить в коде имя одного элемента формы - поля текстового документа.
К публикации прилагается обработка с реализацией этого алгоритма, в которой есть обычная и управляемая форма. Обработка предназначена для работы в толстом клиенте управляемого или обычного приложения. При работе с управляемой формой есть незначительные отличия в коде. Например, восстанавливать положение курсора приходится через отложенный вызов процедуры, через обработчик ожидания.
Алгоритм был создан с целью применения в новой версии универсальной подсистемы Динамические подписки на события v.3 . Не проходите мимо этой разработки, она может облегчить поддержку ваших баз:
У меня есть страница с множеством текстовых полей. Когда кто-то нажимает на ссылку, я хочу, чтобы слово или два были вставлены туда, где находится курсор, или добавлены к текстовому полю с фокусом.
Как я могу это сделать? Возможно ли это вообще, так как что, если фокус находится на элементе radio / dropdown / non textbox? Можно ли запомнить последнее сосредоточенное на текстовом поле?
Я предполагаю, что это возможно, потому что это основа редакторов WYSISYG, как это сделать, я не знаю.
Спасибо, что задали этот вопрос . теперь я могу вставить "[версию]" в курсор с моим расширением Chrome!
Если вы ищете простой модуль с поддержкой отмены, попробуйте insert-text-textarea . Если вам нужна поддержка IE8 +, попробуйте пакет insert-text-at-cursor .
Это отлично работает, но не обрабатывает замену выделенного текста, как все текстовые редакторы. Это может не понадобиться для исходного вопроса автора, но если вам это нужно, вы можете просто заменить 'strPos' на 'txtArea.selectionEnd'. Мой ответ ниже показывает это, наряду с удалением кода обнаружения браузера, если вам не требуется поддержка более старых версий IE.
Может быть, более короткая версия, было бы легче понять?
Вы также можете восстановить каретку позиции после изменения значения с: document.getElementById("txt").selectionStart = caretPos + txtToAdd.length .
Одобренный ответ Джорджа Клагхорна отлично подошел для простой вставки текста в позиции курсора. Если пользователь выбрал текст, и вы хотите, чтобы этот текст был заменен (по умолчанию используется большинство текста), вам нужно внести небольшое изменение при установке переменной 'back'.
Кроме того, если вам не нужно поддерживать более старые версии IE, современные версии поддерживают textarea.selectionStart, так что вы можете убрать все обнаружение браузера и специфический для IE код.
Вот упрощенная версия, которая работает как минимум для Chrome и IE11 и обрабатывает замену выделенного текста.
Это хорошо, но не учитывает элемент maxlength , поэтому результирующее значение после вставки может быть длиннее максимального.
Код выше не работал для меня в IE. Вот код, основанный на этом ответе .
Я вынул, getElementById чтобы я мог ссылаться на элемент по-другому.
РЕДАКТИРОВАТЬ: Добавлен работающий фрагмент, jQuery не используется .
Является ли элемент объектом jquery или нет? element.value и element.focus () не могут работать одновременно .
Да, я написал этот ответ 7 лет назад. На данный момент IE 11 является хорошей минимально поддерживаемой версией, и код выше работает там.
используя ответ @quick_sliv:
Как вставить текст в текущую позицию курсора TextBox через JQuery и JavaScript
- Найти текущую позицию курсора
- Получить текст для копирования
- Установить текст там
- Обновить позицию курсора
Здесь у меня есть 2 текстовых поля и кнопка. Я должен нажать на определенную позицию в текстовом поле, а затем нажать на кнопку, чтобы вставить текст из другого текстового поля в положение предыдущего текстового поля.
Основная проблема здесь заключается в том, чтобы получить текущую позицию курсора, куда мы будем вставлять текст.
Добавление текста в текущую позицию курсора состоит из двух шагов:
- Добавление текста в текущей позиции курсора
- Обновление текущей позиции курсора
Протестировано в Chrome 48, Firefox 45, IE 11 и Edge 25
Я думаю, что вы могли бы использовать следующий JavaScript для отслеживания последнего текстового поля:
Предыдущее решение (props to gclaghorn) использует textarea и рассчитывает положение курсора, так что это может быть лучше для того, что вы хотите. С другой стороны, этот будет более легким, если это то, что вы ищете.
Отличная идея. Я использовал jquery, чтобы к каждому текстовому полю, в котором был определенный класс, применялось это событие, вместо того, чтобы помещать «onfocus = . » в HTML каждого текстового поля. Но хороший подход :)
Принятый ответ не работал для меня в Internet Explorer 9. Я проверил его, и обнаружение браузера не работает должным образом, он обнаружил ff (firefox), когда я был в Internet Explorer.
Я только что сделал это изменение:
В результате получается следующий код:
Этот плагин JQuery дает вам готовый способ выбора / манипулирования кареткой.
Вы можете только сфокусировать нужное текстовое поле и вставить туда текст. нет никакого способа узнать, где фокус AFAIK (возможно, взаимодействующий по всем узлам DOM?).
проверьте этот стекопоток - у него есть решение: как узнать, какой элемент DOM находится в фокусе?
Редактирование содержимого, выбор HTML или любого другого элемента DOM
Если вы пытаетесь вставить курсор в a , это становится намного сложнее, особенно если в редактируемом контейнере есть дочерние элементы.
Мне очень повезло с использованием библиотеки Rangy :
Он имеет массу замечательных функций, таких как:
- Сохранить позицию или выбор
- Затем, позже, восстановить позицию или выбор
- Получить выделенный HTML или обычный текст
- Среди многих других
Онлайн-демонстрация не работала, когда я проверял последний раз, однако в репозитории есть рабочие демонстрации. Для начала просто загрузите репо из Git или NPM, а затем откройте ./rangy/demos/index.html
Это делает работу с Paret Pos и выбор текста на одном дыхании!
Ответ на этот вопрос был опубликован так давно, и я наткнулся на него с помощью поиска Google. HTML5 предоставляет API HTMLInputElement , который включает в setRangeText () метод, который заменяет диапазон текста в или элемент с новой строки:
Вышеуказанное заменит выбор, сделанный внутри, element на abc . Вы также можете указать, какую часть входного значения заменить:
Вышеуказанное заменило бы 4-6-й символы входного значения на abc . Вы также можете указать, как должен быть установлен выбор после замены текста, указав одну из следующих строк в качестве 4-го параметра:
- 'preserve' попытки сохранить выбор. Это по умолчанию.
- 'select' выбирает вновь вставленный текст.
- 'start' перемещает выделение непосредственно перед вставленным текстом.
- 'end' перемещает выделение сразу после вставленного текста.
Совместимость браузера
Я хотел бы создать простую функцию, которая добавляет текст в текстовую область в позиции курсора пользователя. Это должна быть чистая функция. Только основы. Я могу понять остальное.
Если вы ищете простой модуль с поддержкой отмены, попробуйте insert-text-textarea . Если вам нужна поддержка IE8 +, попробуйте пакет insert-text-at-cursor .
@ user340140, ваше исправление "потеря позиции каретки" работает, только если я сосредоточу внимание на вводе прямо перед строками, которые вы предлагаете. Кажется, невозможно изменить выделение на
Есть небольшая проблема с этим кодом: selectionStart это числовое значение, и поэтому его следует сравнивать, 0 а не '0' , и, вероятно, следует использовать ===
Ради правильного Javascript
Не рекомендуется расширять прототип объектов, которыми вы не владеете. Просто сделайте это обычной функцией, и она будет работать так же хорошо.
Это очищает буфер отмены для элемента редактирования после установки this.value = . . Есть ли способ сохранить это?
Новый ответ:
Однако я не уверен в поддержке этого браузера.
Старый ответ:
Чистая JS-модификация ответа Эрика Пукинскиса:
Протестировано в Chrome 47, 81 и Firefox 76.
Если вы хотите изменить значение выделенного в данный момент текста во время ввода в том же поле (для автозаполнения или аналогичного эффекта), передайте document.activeElement в качестве первого параметра.
Это не самый элегантный способ сделать это, но он довольно простой.
Точки с запятой @Phoenix в Javascript не обязательны. Работает и без них. Хотя вы можете редактировать через точку с запятой, если хотите. Ничего особенного.
Я сделал демонстрацию на JSFiddle. Он также работает с использованием Version 54.0.2813.0 canary (64-bit) Chrome Canary 54.0.2813.0. Наконец, если вы хотите вставить его в текстовое поле по идентификатору, используйте document.getElementById('insertyourIDhere') вместо el в функции.
Привет, @ErikAigner! Я плохо, не знал, что на этот вопрос ответили двое Эрика. Я имел в виду Erik Pukinskis . Я обновлю ответ, чтобы лучше отразить это.
Простое решение, которое работает в firefox, chrome, opera, safari и edge, но, вероятно, не будет работать в старых браузерах IE.
setRangeText функция позволяет заменить текущий выбор предоставленным текстом или, если нет выбора, вставить текст в позицию курсора. Насколько я знаю, он поддерживается только firefox.
Для других браузеров существует команда "insertText", которая влияет только на элемент html, в котором в данный момент находится фокус, и имеет такое же поведение, как setRangeText
Частично навеян этой статьей
Это почти правильный путь. Статья, на которую вы ссылаетесь, предлагает полное решение в виде пакета: insert-text-at-cursor . Однако я предпочитаю, execCommand потому что он поддерживает undo и сделал insert-text-textarea . Нет поддержки IE, но меньше
Да, execCommand используется для других браузеров, для firefox вместо этого используется функция setRangeText.
Рамаст, это не то, что делает ваш код. Он будет использовать setRangeText, а не execCommand для любого браузера, который его определяет (большинство). Для описываемого поведения необходимо сначала вызвать document.execCommand, а затем проверить возвращаемое значение. Если это false, используйте target.setRangeText.
@Jools, если поддерживается setRangeText, почему бы не использовать его вместо execCommand? Почему мне нужно сначала попробовать execCommand?
Ответ Раба отлично работает, но не для Microsoft Edge, поэтому я добавил небольшую адаптацию для Edge:
Мне нравится простой javascript, и у меня обычно есть jQuery. Вот что я придумал на основе mparkuk :
Если пользователь не касается ввода после вставки текста, событие input никогда не запускается, и атрибут value не будет отражать изменение. Поэтому важно инициировать событие ввода после программной вставки текста. Недостаточно сфокусировать поле.
Ниже приводится копия ответа Снорварга с триггером ввода в конце:
Читайте также: