Можно ли вставить текст в текстовую область и обновить очередь отмены/повтора?

Несколько дней назад я опубликовал вопрос о том, как обновить текст в Internet Explorer. Как оказалось, использованный метод не работает и в Firefox.

Это заставило меня задуматься, есть ли способ изменить значение текстовой области, а также обновить очередь отмены/повторения (вызов ctrl-Z или document.execCommand('undo');)

Пока я нашел две возможности, но они не работают во всех браузерах:

Опция 1:

var event = document.createEvent('TextEvent');
event.initTextEvent('textInput', true, true, null, text, 9, "en-US");
textarea.focus();
textarea[0].setSelectionRange(selection.start, selection.end);
textarea[0].dispatchEvent(event);

Примечание. Не работает в IE (вообще) и Firefox.

Вариант 2:

document.execCommand("insertText", false, "the text to insert");

Не работает в IE (проверено под 9, но вроде вообще не реализовано), в других браузерах не знаю.


person Cyril N.    schedule 06.11.2013    source источник
comment
это не реализовано в IE, включая IE11, что очень расстраивает! Хотя в Edge работает.   -  person w.stoettinger    schedule 23.10.2017


Ответы (4)


Решение, которое я придумал до сих пор, это одно, но я открыт для лучших идей:

Я проверяю наличие insertText через document.queryCommandSupported. Если он существует, я его использую. Если нет, я просто заменяю текст:

var text = "hello world",
    textarea = jQuery("textarea"),
    selection = {'start': textarea[0].selectionStart, 'end': textarea[0].selectionEnd};

if (document.queryCommandSupported('insertText')) {
    document.execCommand('insertText', false, text);
}
else {
    textarea.val(textarea.val().substring(0, selection.start) + text + textarea.val().substring(selection.end, textarea.val().length));
}
person Cyril N.    schedule 06.11.2013
comment
Я тоже это ищу, и insertText работает, но все равно немного портит историю отмены/повтора. См. jsfiddle.net/rudiedirkx/k4spa0dv. После отмены и повторного выполнения нескольких программных изменений он теряет последние несколько элементов истории, так что повтор не изменит все... Есть идеи? (хром кстати) - person Rudie; 15.01.2015
comment
document.execCommand возвращает true, если команда была выполнена успешно, я использовал возвращаемое значение вместо того, чтобы сначала проверять queryCommandSupported. Также не забудьте обновить позицию каретки с помощью .setSelectionRange(start,end) после того, как вы изменили значение без execCommand. - person w.stoettinger; 23.10.2017
comment
Примечание! Это не работает для Firefox! Команда insertText поддерживается, но только для contenteditable элементов. Не для текстового поля. - person Nux; 31.12.2019

Вариант 1 работает хорошо на данный момент (19 августа 2016 г.), но он устарел в Chrome для одного из будущих выпусков. Отправка события генерирует следующее предупреждение:

Событие DOM, сгенерированное из JavaScript, вызвало действие по умолчанию в браузере. Такое поведение является нестандартным и будет удалено в M53 примерно в сентябре 2016 года. См. https://www.chromestatus.com/features/5718803933560832 для более подробной информации.

person Michal Filip    schedule 19.08.2016
comment
Отлично!.. шаг вперед два шага назад. :п - person Cyril N.; 19.08.2016

Кажется, что на сегодняшний день все современные браузеры поддерживают ваш вариант №1, dispatchEvent. Подробнее здесь:

http://help.dottoro.com/ljrinokx.php

person Stan Lin    schedule 04.03.2015
comment
По-прежнему испорчена история (Chrome): jsfiddle.net/rudiedirkx/k4spa0dv после отмены и повторного выполнения несколько раз он полностью запутался, и история повторов/отмен потеряна. Фаерфокс вообще не работает. - person Rudie; 06.03.2015
comment
Кажется, для этого до сих пор нет кросс-браузерного решения. По крайней мере, IE не работает должным образом ни с одним из предложенных методов в jsfiddle. Какой позор. - person Joshua Muheim; 14.06.2017

Только браузеры, поддерживающие document.execCommand("insertText"), имеют поддержку undo (на данный момент: Chrome, Safari, Opera). Другие браузеры имеют различные способы вставки текста, но не поддерживают undo.

Попробуйте insert-text-textarea обернуть некоторые решения на этой странице для поддержка современных браузеров. Если вам нужна поддержка IE8+, попробуйте insert-text-at-cursor пакет.

person fregante    schedule 29.03.2019