admin管理员组文章数量:1332395
I have a page with a very long textarea used for editing large amounts of texts. Normally, as you type, when the caret approaches the bottom of the textarea, the page will automatically scroll to keep the caret always within the viewport (Firefox will scroll by a single line at a time, Chrome will scroll the caret into the center of the viewport).
My problem es from the fact that I am programmatically changing the contents of the text area based on what the user types. In some cases this involves adding extra content, thus pushing the caret out of view.
As soon as the user hits a key, the autoscroll kicks in and the caret is scrolled into view -- but not before, so as the user is typing they lose sight of the caret. I had hoped I could simply trigger key events on the textarea for the browser to autoscroll, but triggered events don't fully emulate user behavior and I do not get a response.
The only solution I can see now is to try to get the XY coordinates of the caret by:
- Finding the character position of the caret.
- Building a div that mirrors the content of the textarea with a marker at the caret position.
- Measuring the position of the marker.
Is there a simpler way to do this?
I have a page with a very long textarea used for editing large amounts of texts. Normally, as you type, when the caret approaches the bottom of the textarea, the page will automatically scroll to keep the caret always within the viewport (Firefox will scroll by a single line at a time, Chrome will scroll the caret into the center of the viewport).
My problem es from the fact that I am programmatically changing the contents of the text area based on what the user types. In some cases this involves adding extra content, thus pushing the caret out of view.
As soon as the user hits a key, the autoscroll kicks in and the caret is scrolled into view -- but not before, so as the user is typing they lose sight of the caret. I had hoped I could simply trigger key events on the textarea for the browser to autoscroll, but triggered events don't fully emulate user behavior and I do not get a response.
The only solution I can see now is to try to get the XY coordinates of the caret by:
- Finding the character position of the caret.
- Building a div that mirrors the content of the textarea with a marker at the caret position.
- Measuring the position of the marker.
Is there a simpler way to do this?
Share Improve this question edited Oct 25, 2012 at 5:55 Rhyono 2,4682 gold badges27 silver badges42 bronze badges asked Oct 24, 2012 at 21:38 blocksblocks 9382 gold badges8 silver badges15 bronze badges 1- 1 May be related: stackoverflow./a/12738472/1615483 – Paul S. Commented Oct 24, 2012 at 22:22
3 Answers
Reset to default 1[The previous solution was not patible with Chrome (WebKit?)]
IF, a BIG if, the extra content is appended to the end of the input, the exercise below may offer the solution:
<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>
I hate to suggest adding a whole library for one problem, but consider looking at CodeMirror. It handles all such stuff for you, and is fairly simple to use.
http://codemirror/
Since you already are on the javascript path and suppose a dynamic textarea height would pose a design issue, you could try autoresizing your textarea by content:
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;
}
I know this does not answer the specifics outlined in your post but it provides an alternative approach fitting your question title. So even if it's not useful for you, it may be just that for others visiting this question.
I personally hate too small text areas and dependin on the case, would prefer them autosizing.
本文标签: javascriptHow do I keep a textarea39s caret always within the viewportStack Overflow
版权声明:本文标题:javascript - How do I keep a textarea's caret always within the viewport? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742281368a2446154.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论