Ответ 1
Я ненавижу предлагать добавить целую библиотеку для одной проблемы, но подумайте над CodeMirror. Он обрабатывает все такие вещи для вас и довольно прост в использовании.
У меня есть страница с очень длинным текстовым полем, используемым для редактирования большого количества текстов. Обычно, когда вы набираете, когда каретка приближается к нижней части текстового поля, страница автоматически прокручивается, чтобы сохранить курсор всегда в пределах области просмотра (Firefox будет прокручиваться по одной строке за раз, Chrome будет прокручивать каретку в центр в окне просмотра).
Моя проблема связана с тем, что я программно меняю содержимое текстовой области на основе того, что пользователь набирает. В некоторых случаях это связано с добавлением дополнительного контента, тем самым выталкивая каретку вне поля зрения.
Как только пользователь нажимает клавишу, автопрокрутка запускается, и каретка прокручивается в представление - но не раньше, так как пользователь печатает, они теряют из виду каретку. Я надеялся, что я могу просто инициировать ключевые события в текстовом поле для браузера для автоматического прокрутки, но инициированные события не полностью эмулируют поведение пользователя, и я не получаю ответа.
Единственное решение, которое я вижу сейчас, это попытаться получить координаты XY каретки:
Есть ли более простой способ сделать это?
Я ненавижу предлагать добавить целую библиотеку для одной проблемы, но подумайте над CodeMirror. Он обрабатывает все такие вещи для вас и довольно прост в использовании.
[Предыдущее решение не совместимо с Chrome (WebKit?)]
IF, BIG, если дополнительный контент добавляется к концу ввода, упражнение ниже может предложить решение:
<html>
<head>
<script>
function btnGoOnClick(ctrl)
{
//-- For this POC the text content is reset to 160 lines of dummy text -
//----------------------------------------------------------------------
ctrl.value = "";
for (var i = 0; i < 160; ++i)
{
ctrl.value += "dummy!\n";
}
//-- Then the carret is set to the last position -----------------------
//----------------------------------------------------------------------
if (ctrl.createTextRange)
{
//-- IE specific methods to move the carret to the last position
var textRange = ctrl.createTextRange();
textRange.moveStart("character", ctrl.value.length);
textRange.moveEnd("character", 0);
textRange.select();
}
else
{
//-- Mozilla and WebKit methods to move the carret
ctrl.setSelectionRange(ctrl.value.length, ctrl.value.length);
}
//-- For WebKit, the scroll bar has to be explicitly set ---------------
//----------------------------------------------------------------------
ctrl.scrollTop = ctrl.scrollHeight;
//-- Almost there: make sure the control has fucos and is into view ----
//----------------------------------------------------------------------
ctrl.focus();
ctrl.scrollIntoView(false);
}
</script>
</head>
<body>
<form name="form">
<input type="button" name="btnGo" value="Go!" onClick="btnGoOnClick(document.form.text);" />
<div style="height: 1000px"></div>
<textarea name="text" rows="80"></textarea>
</form>
</body>
</html>
Поскольку вы уже находитесь на пути javascript и предположите, что высота динамической textarea создаст проблему с дизайном, вы можете попробовать выполнить автореализацию своего текстового поля по контенту:
function resizeTextarea(textarea) {
var lines = textarea.value.split('\n');
var width = textarea.cols;
var height = 1;
for (var i = 0; i < lines.length; i++) {
var linelength = lines[i].length;
if (linelength >= width) {
height += Math.ceil(linelength / width);
}
}
height += lines.length;
textarea.rows = height;
}
Я знаю, что это не отвечает спецификациям, изложенным в вашем сообщении, но предоставляет альтернативный подход, подходящий для вашего вопроса. Поэтому, даже если это вам не полезно, может быть, это просто для других, которые посещают этот вопрос.
Я лично ненавижу слишком маленькие области текста и зависит от этого случая, предпочла бы их автосоздание.