Можно если не WebSocket, то использовать технологию ajax (fetch), которая будет периодически принимать обновлённое содержимое поля для ввода. В следующем простейшем примере будем использовать три файла на сервере:
index.html
<textarea id=txt oninput='send(this.value)'></textarea>
<script>
async function send(text){await fetch('script.php?text=' + text)};
async function get(){txt.value = await (await fetch('file.txt')).text()};
get();
setInterval(get, 5000);
txt.focus();
</script>
script.php
$text = $_GET['text'];
$file = fopen('file.txt', 'w');
fwrite($file, $text);
fclose($file);
file.txt - изначально пустой файл.
Все три файла в этом примере должны быть в одной папке.
Суть работы такова: когда каждый, у кого открыт index.html делает любое изменение содержимого
textarea, все остальные, у кого он открыт, видят это изменение в режиме реального времени. Это даже можно назвать примером простейшего чата на несколько строк. Можно переделать и использовать для отслеживания в реальном времени того, что вводят в поле для ввода.
Второй вариант: всё, что вводит, исправляет и вытирает пользователь, записывается в массив, потом этот массив отправляется на сервер, от куда его можно скачать и прочитать в любое удобное время. При чтении происходит анимация, воспроизводящая запись всех действий пользователя в поле для ввода текста. Вот упрощённая рабочая схема:
<textarea id=txt cols=50 rows=10 oninput='array.push(this.value)' placeholder='введите текст:'></textarea><br /><br />
<button onclick='read()'> прочитать </button>
<button onclick='reset()'> очистить </button>
<script>
let array = [];
const read = _ => {
let index = 0;
let interval = setInterval(function(){
txt.value = array[index];
index ++;
if(index >= array.length) clearInterval(interval);
}, 300);
}
const reset = _ => {
txt.value = '';
array = [];
}
txt.focus();
</script>