텍스트 입력 필드 내에서 커서 위치 (문자 단위) 가져 오기


211

입력 필드 내에서 캐럿 위치를 얻으려면 어떻게해야합니까?

Google을 통해 몇 가지 비트와 조각을 찾았지만 총알은 없습니다.

기본적으로 jQuery 플러그인과 같은 것이 이상적이므로 간단히 할 수 있습니다.

$("#myinput").caretPosition()

2
'커서 위치'를 검색하면 더 많은 인기를 얻을 수 있으며 SO에 대한 몇 가지 주제가 있습니다.
Alec


2
@CMS에서 위치를 찾는 <input>것이에서 수행하는 것보다 훨씬 간단합니다 <textarea>.
Andrew Mao

1
@AndrewMao : 텍스트가 스크롤되고 캐럿이 size문자를 지나면 더 어려워집니다 .
Dan Dascalescu

@ alec : 캐럿 대신 커서를 검색하면 더 많은 결과를 얻을 수 있습니다. 다른 곳에서 지적했듯이 캐럿 이 더 적절한 용어라는 것을 알았습니다 . 커서는 잠시 아무것도의 위치를 나타냅니다 캐럿이 텍스트에서 특정 위치를 나타냅니다.
Suncat2000

답변:


247

더 쉬운 업데이트 :

field.selectionStart 이 답변에 예제를 사용하십시오 .

이것을 지적 해 주신 @commonSenseCode에게 감사합니다.


이전 답변 :

이 솔루션을 찾았습니다. jquery 기반이 아니지만 jquery에 통합하는 데 아무런 문제가 없습니다.

/*
** Returns the caret (cursor) position of the specified text field (oField).
** Return value range is 0-oField.value.length.
*/
function doGetCaretPosition (oField) {

  // Initialize
  var iCaretPos = 0;

  // IE Support
  if (document.selection) {

    // Set focus on the element
    oField.focus();

    // To get cursor position, get empty selection range
    var oSel = document.selection.createRange();

    // Move selection start to 0 position
    oSel.moveStart('character', -oField.value.length);

    // The caret position is selection length
    iCaretPos = oSel.text.length;
  }

  // Firefox support
  else if (oField.selectionStart || oField.selectionStart == '0')
    iCaretPos = oField.selectionDirection=='backward' ? oField.selectionStart : oField.selectionEnd;

  // Return results
  return iCaretPos;
}

9
else if (oField.selectionStart || oField.selectionStart == '0')일 수else if (typeof oField.selectionStart==='number')
user2428118

"oField.focus ()"의 아이디어는 무엇입니까? 이 줄이 없으면 저에게 효과적입니다. 입력에 blur 이벤트를 사용하고 콜백 내에서 해당 기능을 실행하는 경우주의하십시오.
Kirill Reznikov

IE에서 테스트하고 있습니까? 섹션 전체가 IE에서만 실행됩니다. IE에는 전역 선택 만 있습니다. 그래서 document.selection그렇지 않은 field.selection것입니다. 또한 IE 7 (8 이상에서는 여전히 가능한지 알 수 없음)에서 무언가를 선택한 다음 선택을 잃지 않고 필드에서 Tab 키를 눌러도 가능합니다. 이 방법으로 텍스트를 선택했지만 필드에 초점이 맞지 않으면 document.selection0 선택을 반환합니다. 그렇기 때문에이 버그의 해결 방법으로를 읽기 전에 요소에 집중해야합니다 document.selection.
bezmax

크롬과 파이어 폭스에 대해 항상 0을 받고
Kaushik Thanki

117

맥스 덕분입니다

누군가가 그것을 사용하고 싶다면 그의 답변에있는 기능을 jQuery에 래핑했습니다.

(function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if ('selectionStart' in input) {
            // Standard-compliant browsers
            return input.selectionStart;
        } else if (document.selection) {
            // IE
            input.focus();
            var sel = document.selection.createRange();
            var selLen = document.selection.createRange().text.length;
            sel.moveStart('character', -input.value.length);
            return sel.text.length - selLen;
        }
    }
})(jQuery);

3
하지가 input = $(this).get(0)같은 input = this?
Mic

4
@Mic no, jQuery 플러그인이 아닙니다. 플러그인 this에서 전체 포장 세트를 나타냅니다. 그의 코드는 여전히 잘못되어 있습니다 this.get(0). 래핑 된 세트를 다시 랩핑해도 아무런 효과가 없기 때문에 코드가 여전히 작동했을 것입니다.
Chev

1
이것은 나에게 잘못된 정보를 제공합니다. 텍스트를 입력 할 때 커서 위치를보고있었습니다. 이것을 보여주는 나의 바이올린은 : jsfiddle.net/fallenreaper/TSwyk
Fallenreaper

1
입력이 숫자 유형일 때 Firefox는 input.selectionStart에서 NS_ERROR_FAILURE를 생성합니다. 입력이 {} catch {}?
niall.campbell

함수에 사용법을 추가하면 새로운 꿀벌에게 좋을 것입니다.
Muhammad Omer Aslam

98

아주 쉽게

업데이트 된 답변

사용 selectionStart, 그것은이다 모든 주요 브라우저와 호환 .

document.getElementById('foobar').addEventListener('keyup', e => {
  console.log('Caret at: ', e.target.selectionStart)
})
<input id="foobar" />

업데이트 : 이것은 유형이 정의되지 않았거나 type="text"입력에 있을 때만 작동합니다 .


2
마우스를 사용하여 위치를 변경하면 콘솔에서 인쇄되지 않습니다. 그것을 고칠 수있는 방법이 있습니까?
Eugene Barsky

3
@EugeneBarsky 클릭 이벤트에 대한 새로운 이벤트 리스너를 추가하십시오. .selectionStart언제라도 속성을 확인할 수 있습니다 ( document.getElementById('foobar').selectionStart). 이벤트 리스너 안에있을 필요는 없습니다.
JJJ

3
입력 유형이 숫자 인 경우 Firefox 또는 Chrome에서 작동하지 않습니다.
Adam R. Grey

26

매우 간단한 해결책이 있습니다. 검증 된 결과로 다음 코드 시도하십시오 -

<html>
<head>
<script>
    function f1(el) {
    var val = el.value;
    alert(val.slice(0, el.selectionStart).length);
}
</script>
</head>
<body>
<input type=text id=t1 value=abcd>
    <button onclick="f1(document.getElementById('t1'))">check position</button>
</body>
</html>

나는 당신에게 fiddle_demo를 주고있다


13
slice상대적으로 비싼 작업이며이 '솔루션'에 아무것도 추가하지 않습니다 el.selectionStart. 슬라이스의 길이와 같습니다. 그냥 돌려주십시오. 또한 다른 솔루션이 더 복잡한 이유는 지원하지 않는 다른 브라우저를 처리하기 때문 selectionStart입니다.
mpen

변수 이름이 같은 코드로 작업 해야하는 작업을 종료했습니다.
Michael Scheper

@Michael Scheper-요소는 'el', 가치는 'val'을 의미합니까? 그것들은 꽤 일반적입니다.
user2782001

6
@ user2782001 : 나는 틀렸다 – 나의 주요 관심사는 함수 이름이었다. f1'user2782001'만큼 의미가 있습니다. 😉
Michael Scheper

16

이제 이것을위한 멋진 플러그인이 있습니다 : 캐럿 플러그인

그런 다음을 사용하여 위치를 얻 $("#myTextBox").caret()거나 설정할 수 있습니다.$("#myTextBox").caret(position)


1
캐럿 플러그인은 textarea 요소가 입력되지 않은 것으로 보입니다
schmidlop

4
<input type = "text"id = "myTextBox"/>에서 작동하고 위 코드를 사용했습니다.
Jens Mikkelsen

14
   (function($) {
    $.fn.getCursorPosition = function() {
        var input = this.get(0);
        if (!input) return; // No (input) element found
        if (document.selection) {
            // IE
           input.focus();
        }
        return 'selectionStart' in input ? input.selectionStart:'' || Math.abs(document.selection.createRange().moveStart('character', -input.value.length));
     }
   })(jQuery);

10

여기에 몇 가지 좋은 답변이 게시되어 있지만 코드를 단순화하고 inputElement.selectionStart지원 확인을 건너 뛸 수 있다고 생각합니다 . 현재 브라우저 사용량 의 1 % 미만을 나타내는 IE8 및 이전 버전 ( 문서 참조 ) 에서만 지원되지 않습니다 .

var input = document.getElementById('myinput'); // or $('#myinput')[0]
var caretPos = input.selectionStart;

// and if you want to know if there is a selection or not inside your input:

if (input.selectionStart != input.selectionEnd)
{
    var selectionValue =
    input.value.substring(input.selectionStart, input.selectionEnd);
}

2

커서 위치 외에 선택한 범위가 필요할 수도 있습니다. 다음은 간단한 함수이며 jQuery가 필요하지 않습니다.

function caretPosition(input) {
    var start = input[0].selectionStart,
        end = input[0].selectionEnd,
        diff = end - start;

    if (start >= 0 && start == end) {
        // do cursor position actions, example:
        console.log('Cursor Position: ' + start);
    } else if (start >= 0) {
        // do ranged select actions, example:
        console.log('Cursor Position: ' + start + ' to ' + end + ' (' + diff + ' selected chars)');
    }
}

입력이 변경되거나 마우스가 커서 위치를 이동할 때마다 입력에서 호출하려고한다고 가정합니다 (이 경우 jQuery 사용 .on()). 성능상의 이유로 이벤트가 쏟아지는 경우 setTimeout()밑줄과 같은 것을 추가하는 것이 좋습니다 _debounce().

$('input[type="text"]').on('keyup mouseup mouseleave', function() {
    caretPosition($(this));
});

그것을 시도하고 싶다면 바이올린이 있습니다 : https://jsfiddle.net/Dhaupin/91189tq7/


0

const inpT = document.getElementById("text-box");
const inpC = document.getElementById("text-box-content");
// swch gets  inputs .
var swch;
// swch  if corsur is active in inputs defaulte is false .
var isSelect = false;

var crnselect;
// on focus
function setSwitch(e) {
  swch = e;
  isSelect = true;
  console.log("set Switch: " + isSelect);
}
// on click ev
function setEmoji() {
  if (isSelect) {
    console.log("emoji added :)");
    swch.value += ":)";
    swch.setSelectionRange(2,2 );
    isSelect = true;
  }

}
// on not selected on input . 
function onout() {
  // الافنت  اون كي اب 
  crnselect = inpC.selectionStart;
  
  // return input select not active after 200 ms .
  var len = swch.value.length;
  setTimeout(() => {
   (len == swch.value.length)? isSelect = false:isSelect = true;
  }, 200);
}
<h1> Try it !</h1>
    
		<input type="text" onfocus = "setSwitch(this)" onfocusout = "onout()" id="text-box" size="20" value="title">
		<input type="text" onfocus = "setSwitch(this)"  onfocusout = "onout()"  id="text-box-content" size="20" value="content">
<button onclick="setEmoji()">emogi :) </button>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.