17

我有一个用于编辑大量文本的文本区域很长的页面。通常,当您键入时,当插入符号接近文本区域的底部时,页面会自动滚动以使插入符号始终保持在视口内(Firefox 将一次滚动一行,Chrome 会将插入符号滚动到视口)。

我的问题来自这样一个事实,即我正在根据用户键入的内容以编程方式更改文本区域的内容。在某些情况下,这涉及添加额外的内容,从而将插入符号推到视野之外。

一旦用户按下一个键,自动滚动就会启动,并且插入符号会滚动到视图中 - 但不是之前,因此当用户键入时,他们会看不到插入符号。我曾希望我可以简单地触发文本区域上的关键事件,让浏览器自动滚动,但触发的事件并不能完全模拟用户行为,我也没有得到响应。

我现在能看到的唯一解决方案是尝试通过以下方式获取插入符号的 XY 坐标:

  1. 查找插入符号的字符位置。
  2. 构建一个 div,在插入符号位置使用标记来镜像 textarea 的内容。
  3. 测量标记的位置。

有没有更简单的方法来做到这一点?

4

3 回答 3

1

我讨厌建议为一个问题添加整个库,但请考虑查看 CodeMirror。它为您处理所有这些事情,并且使用起来相当简单。

http://codemirror.net/

于 2013-02-19T21:46:22.300 回答
0

[之前的解决方案不兼容 Chrome (WebKit?)]

如果,一个大如果,额外的内容附加到输入的末尾,下面的练习可能会提供解决方案:

<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>
于 2012-10-25T06:35:00.600 回答
0

由于您已经在 javascript 路径上并且假设动态 textarea 高度会造成设计问题,您可以尝试按内容自动调整 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;
}

我知道这不能回答您帖子中概述的细节,但它提供了一种适合您的问题标题的替代方法。因此,即使它对您没有用,也可能对其他访问此问题的人有用。

我个人讨厌太小的文本区域,并且视情况而定,更喜欢它们自动调整大小。

于 2013-02-06T09:25:53.523 回答