简体   繁体   English

如何从一开始就以字符形式在textarea中获取插入符号列(不是像素)的位置?

[英]How to get the caret column (not pixels) position in a textarea, in characters, from the start?

How do you get the caret position in a <textarea> using JavaScript? 你如何使用JavaScript获得<textarea>的插入位置?

For example: This is| a text 例如: This is| a text This is| a text

This should return 7 . 这应该返回7

How would you get it to return the strings surrounding the cursor / selection? 如何让它返回光标/选择周围的字符串?

Eg: 'This is', '', ' a text' . 例如: 'This is', '', ' a text'

If the word “is” is highlighted, then it would return 'This ', 'is', ' a text' . 如果单词“is”突出显示,则返回'This ', 'is', ' a text'

With Firefox, Safari (and other Gecko based browsers) you can easily use textarea.selectionStart, but for IE that doesn't work, so you will have to do something like this: 使用Firefox,Safari(以及其他基于Gecko的浏览器),您可以轻松使用textarea.selectionStart,但对于不起作用的IE,您必须执行以下操作:

function getCaret(node) {
  if (node.selectionStart) {
    return node.selectionStart;
  } else if (!document.selection) {
    return 0;
  }

  var c = "\001",
      sel = document.selection.createRange(),
      dul = sel.duplicate(),
      len = 0;

  dul.moveToElementText(node);
  sel.text = c;
  len = dul.text.indexOf(c);
  sel.moveStart('character',-1);
  sel.text = "";
  return len;
}

( complete code here ) 这里完整代码

I also recommend you to check the jQuery FieldSelection Plugin, it allows you to do that and much more... 我还建议你检查jQuery FieldSelection插件,它允许你这样做以及更多......

Edit: I actually re-implemented the above code: 编辑:我实际上重新实现了上面的代码:

function getCaret(el) { 
  if (el.selectionStart) { 
    return el.selectionStart; 
  } else if (document.selection) { 
    el.focus(); 

    var r = document.selection.createRange(); 
    if (r == null) { 
      return 0; 
    } 

    var re = el.createTextRange(), 
        rc = re.duplicate(); 
    re.moveToBookmark(r.getBookmark()); 
    rc.setEndPoint('EndToStart', re); 

    return rc.text.length; 
  }  
  return 0; 
}

Check an example here . 点击这里查看示例。

Updated 5 September 2010 2010年9月5日更新

Seeing as everyone seems to get directed here for this issue, I'm adding my answer to a similar question, which contains the same code as this answer but with full background for those who are interested: 看到每个人似乎都在这里针对这个问题,我将我的答案添加到一个类似的问题,其中包含与此答案相同的代码,但对于那些感兴趣的人有完整的背景:

IE's document.selection.createRange doesn't include leading or trailing blank lines IE的document.selection.createRange不包括前导或尾随空行

To account for trailing line breaks is tricky in IE, and I haven't seen any solution that does this correctly, including any other answers to this question. 在IE中考虑尾随换行是很棘手的,我没有看到任何正确执行此操作的解决方案,包括此问题的任何其他答案。 It is possible, however, using the following function, which will return you the start and end of the selection (which are the same in the case of a caret) within a <textarea> or text <input> . 但是,可以使用以下函数,它将返回<textarea>或text <input>选择的开始和结束(在插入符号的情况下相同)。

Note that the textarea must have focus for this function to work properly in IE. 请注意,textarea必须具有焦点才能使此功能在IE中正常工作。 If in doubt, call the textarea's focus() method first. 如果有疑问,请先调用textarea的focus()方法。

function getInputSelection(el) {
    var start = 0, end = 0, normalizedValue, range,
        textInputRange, len, endRange;

    if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
        start = el.selectionStart;
        end = el.selectionEnd;
    } else {
        range = document.selection.createRange();

        if (range && range.parentElement() == el) {
            len = el.value.length;
            normalizedValue = el.value.replace(/\r\n/g, "\n");

            // Create a working TextRange that lives only in the input
            textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());

            // Check if the start and end of the selection are at the very end
            // of the input, since moveStart/moveEnd doesn't return what we want
            // in those cases
            endRange = el.createTextRange();
            endRange.collapse(false);

            if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                start = end = len;
            } else {
                start = -textInputRange.moveStart("character", -len);
                start += normalizedValue.slice(0, start).split("\n").length - 1;

                if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                    end = len;
                } else {
                    end = -textInputRange.moveEnd("character", -len);
                    end += normalizedValue.slice(0, end).split("\n").length - 1;
                }
            }
        }
    }

    return {
        start: start,
        end: end
    };
}

I modified the above function to account for carriage returns in IE. 我修改了上面的函数来解释IE中的回车问题。 It's untested but I did something similar with it in my code so it should be workable. 它没有经过测试,但我在我的代码中做了类似的事情,所以它应该是可行的。

function getCaret(el) {
  if (el.selectionStart) { 
    return el.selectionStart; 
  } else if (document.selection) { 
    el.focus(); 

    var r = document.selection.createRange(); 
    if (r == null) { 
      return 0; 
    } 

    var re = el.createTextRange(), 
    rc = re.duplicate(); 
    re.moveToBookmark(r.getBookmark()); 
    rc.setEndPoint('EndToStart', re); 

    var add_newlines = 0;
    for (var i=0; i<rc.text.length; i++) {
      if (rc.text.substr(i, 2) == '\r\n') {
        add_newlines += 2;
        i++;
      }
    }

    //return rc.text.length + add_newlines;

    //We need to substract the no. of lines
    return rc.text.length - add_newlines; 
  }  
  return 0; 
}

If you don't have to support IE, you can use selectionStart and selectionEnd attributes of textarea . 如果您不必支持IE,则可以使用textarea selectionStartselectionEnd属性。

To get caret position just use selectionStart : 要获得插入位置,只需使用selectionStart

function getCaretPosition(textarea) {
  return textarea.selectionStart
}

To get the strings surrounding the selection, use following code: 要获取选择周围的字符串,请使用以下代码:

function getSurroundingSelection(textarea) {
  return [textarea.value.substring(0, textarea.selectionStart)
         ,textarea.value.substring(textarea.selectionStart, textarea.selectionEnd)
         ,textarea.value.substring(textarea.selectionEnd, textarea.value.length)]
}

Demo on JSFiddle . 演示JSFiddle

See also HTMLTextAreaElement docs . 另请参见HTMLTextAreaElement文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM