[javascript] 텍스트 영역에서 캐럿 열 (픽셀이 아닌) 위치를 문자로 시작하는 방법은 무엇입니까?

<textarea>JavaScript를 사용하여 캐럿 위치를 어떻게 얻 습니까?

예를 들면 다음과 같습니다. This is| a text

이 반환되어야합니다 7.

커서 / 선택 영역을 둘러싼 문자열을 어떻게 반환합니까?

예 : 'This is', '', ' a text'.

“is”라는 단어가 강조 표시되면을 반환 'This ', 'is', ' a text'합니다.



답변

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;
}

( 여기에서 완전한 코드 )

또한 jQuery FieldSelection 플러그인 을 확인하는 것이 좋습니다 .

편집 : 실제로 위 코드를 다시 구현했습니다.

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;
}

예를 확인 하십시오 .


답변

2010 년 9 월 5 일 업데이트

모든 사람 이이 문제에 대해 여기에서 지시하는 것처럼 보니 비슷한 질문에 대한 답변을 추가합니다.이 답변과 동일한 코드가 포함되어 있지만 관심있는 사람들을위한 배경 지식이 있습니다.

IE의 document.selection.createRange에는 선행 또는 후행 빈 줄이 포함되지 않습니다

IE에서 후행 줄 바꿈을 설명하는 것은 까다 롭고이 질문에 대한 다른 답변을 포함하여 올바르게 수행하는 솔루션을 보지 못했습니다. 그러나 다음 함수를 사용하면 a <textarea>또는 text 내에서 선택 항목의 시작과 끝 (캐럿의 경우와 동일)을 반환 할 수 있습니다 <input>.

IE에서이 기능이 제대로 작동하려면 텍스트 영역에 포커스가 있어야합니다. 확실하지 않은 경우 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
    };
}


답변

IE의 캐리지 리턴을 설명하기 위해 위 함수를 수정했습니다. 테스트되지 않았지만 코드에서 이와 비슷한 작업을 수행 했으므로 실행 가능해야합니다.

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;
}


답변

IE를 지원하지 않아도되는 경우 selectionStart및의 selectionEnd속성을 사용할 수 있습니다 textarea.

캐럿 위치를 얻으려면 다음을 사용하십시오 selectionStart.

function getCaretPosition(textarea) {
  return textarea.selectionStart
}

선택을 둘러싼 문자열을 얻으려면 다음 코드를 사용하십시오.

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)]
}

JSFiddle 데모 .

HTMLTextAreaElement docs 도 참조하십시오 .


답변