development

텍스트 영역에서 jQuery 커서 위치 설정

big-blog 2020. 2. 18. 22:48
반응형

텍스트 영역에서 jQuery 커서 위치 설정


jQuery를 사용하여 텍스트 필드에서 커서 위치를 어떻게 설정합니까? 내용이있는 텍스트 필드가 있고 필드에 초점을 맞출 때 사용자 커서를 특정 오프셋에 배치하려고합니다. 코드는 다음과 같아야합니다.

$('#input').focus(function() {
  $(this).setCursorPosition(4);
});

해당 setCursorPosition 함수의 구현은 어떤 모양입니까? abcdefg 컨텐츠가있는 텍스트 필드가있는 경우이 호출로 인해 커서가 abcd ** | ** efg로 배치됩니다.

Java에는 비슷한 기능인 setCaretPosition이 있습니다. 자바 스크립트에 대해 비슷한 방법이 있습니까?

업데이트 : jQuery와 함께 작동하도록 CMS 코드를 다음과 같이 수정했습니다.

new function($) {
  $.fn.setCursorPosition = function(pos) {
    if (this.setSelectionRange) {
      this.setSelectionRange(pos, pos);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      if(pos < 0) {
        pos = $(this).val().length + pos;
      }
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
}(jQuery);

두 가지 기능이 있습니다.

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

그런 다음 다음과 같이 setCaretToPos를 사용할 수 있습니다.

setCaretToPos(document.getElementById("YOURINPUT"), 4);

jQuery에서의 사용법을 보여주는 a textareaa 모두를 사용한 라이브 예제 input:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  } else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos(input, pos) {
  setSelectionRange(input, pos, pos);
}

$("#set-textarea").click(function() {
  setCaretToPos($("#the-textarea")[0], 10)
});
$("#set-input").click(function() {
  setCaretToPos($("#the-input")[0], 10);
});
<textarea id="the-textarea" cols="40" rows="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</textarea>
<br><input type="button" id="set-textarea" value="Set in textarea">
<br><input id="the-input" type="text" size="40" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit">
<br><input type="button" id="set-input" value="Set in input">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

2016 년 현재 Chrome, Firefox, IE11, 심지어 IE8에서도 테스트 및 작업 중입니다 (마지막 참조 ; 스택 스 니펫은 IE8을 지원하지 않습니다).


jQuery 솔루션은 다음과 같습니다.

$.fn.selectRange = function(start, end) {
    if(end === undefined) {
        end = start;
    }
    return this.each(function() {
        if('selectionStart' in this) {
            this.selectionStart = start;
            this.selectionEnd = end;
        } else if(this.setSelectionRange) {
            this.setSelectionRange(start, end);
        } else if(this.createTextRange) {
            var range = this.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    });
};

이것으로 할 수 있습니다

$('#elem').selectRange(3,5); // select a range of text
$('#elem').selectRange(3); // set cursor position

여기에있는 솔루션은 jQuery 확장 코드를 제외하고는 옳습니다.

확장 기능은 선택한 각 요소를 반복하고 this연결 지원으로 돌아갑니다 . 다음은 올바른 버전 :

$.fn.setCursorPosition = function(pos) {
  this.each(function(index, elem) {
    if (elem.setSelectionRange) {
      elem.setSelectionRange(pos, pos);
    } else if (elem.createTextRange) {
      var range = elem.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  });
  return this;
};

나에게 맞는 해결책을 찾았습니다.

$.fn.setCursorPosition = function(position){
    if(this.length == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    if(this.length == 0) return this;
    var input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    this.setCursorPosition(this.val().length);
            return this;
}

이제 다음을 호출하여 포커스를 요소의 끝으로 이동할 수 있습니다.

$(element).focusEnd();

또는 위치를 지정하십시오.

$(element).setCursorPosition(3); // This will focus on the third character.

이것은 Mac OSX의 Safari 5, jQuery 1.4에서 나를 위해 일했습니다.

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;

나는 이것이 매우 오래된 게시물이라는 것을 알고 있지만 jQuery 만 사용하여 업데이트하는 더 간단한 솔루션을 제공해야한다고 생각했습니다.

function getTextCursorPosition(ele) {   
    return ele.prop("selectionStart");
}

function setTextCursorPosition(ele,pos) {
    ele.prop("selectionStart", pos + 1);
    ele.prop("selectionEnd", pos + 1);
}

function insertNewLine(text,cursorPos) {
    var firstSlice = text.slice(0,cursorPos);
    var secondSlice = text.slice(cursorPos);

    var new_text = [firstSlice,"\n",secondSlice].join('');

    return new_text;
}

ctrl-enter를 사용하여 새 라인을 추가하는 사용법 (Facebook에서와 같이) :

$('textarea').on('keypress',function(e){
    if (e.keyCode == 13 && !e.ctrlKey) {
        e.preventDefault();
        //do something special here with just pressing Enter
    }else if (e.ctrlKey){
        //If the ctrl key was pressed with the Enter key,
        //then enter a new line break into the text
        var cursorPos = getTextCursorPosition($(this));                

        $(this).val(insertNewLine($(this).val(), cursorPos));
        setTextCursorPosition($(this), cursorPos);
    }
});

나는 비판을 받는다. 감사합니다.

업데이트 :이 솔루션은 정상적인 복사 및 붙여 넣기 기능이 작동하지 않도록합니다 (예 : ctrl-c, ctrl-v).이 부분이 다시 작동하도록 나중에 편집해야합니다. 그렇게하는 방법을 알고 있다면 여기에 의견을 보내 주시면 기꺼이 테스트 해 드리겠습니다. 감사.


나는 이것을 사용하고있다 : http://plugins.jquery.com/project/jCaret


IE에서 커서를 특정 위치로 이동하면이 코드로 충분합니다.

var range = elt.createTextRange();
range.move('character', pos);
range.select();

텍스트 영역에 텍스트를 삽입하기 전에 초점을 설정 하시겠습니까?

$("#comments").focus();
$("#comments").val(comments);

이것은 크롬에서 나를 위해 작동합니다

$('#input').focus(function() {
    setTimeout( function() {
        document.getElementById('input').selectionStart = 4;
        document.getElementById('input').selectionEnd = 4;
    }, 1);
});

일반적으로 사용자가 재정의하려는 텍스트 필드의 일부 위치를 클릭하거나 탭을 눌러 텍스트 필드에 초점을 맞추기 때문에 마이크로 초 이상 지연이 필요하므로 위치가 나올 때까지 기다려야합니다. 사용자가 설정 한 다음 변경하십시오.


비트 버킷 에서 찾은 코드를 약간 수정

코드는 이제 2 개의 위치가 주어지면 시작 / 종료 지점을 선택 / 강조 할 수 있습니다. FF / Chrome / IE9 / Opera에서 테스트되고 잘 작동합니다.

$('#field').caret(1, 9);

코드는 아래에 나열되어 있으며 몇 줄만 변경되었습니다.

(function($) {
  $.fn.caret = function(pos) {
    var target = this[0];
    if (arguments.length == 0) { //get
      if (target.selectionStart) { //DOM
        var pos = target.selectionStart;
        return pos > 0 ? pos : 0;
      }
      else if (target.createTextRange) { //IE
        target.focus();
        var range = document.selection.createRange();
        if (range == null)
            return '0';
        var re = target.createTextRange();
        var rc = re.duplicate();
        re.moveToBookmark(range.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
      }
      else return 0;
    }

    //set
    var pos_start = pos;
    var pos_end = pos;

    if (arguments.length > 1) {
        pos_end = arguments[1];
    }

    if (target.setSelectionRange) //DOM
      target.setSelectionRange(pos_start, pos_end);
    else if (target.createTextRange) { //IE
      var range = target.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos_end);
      range.moveStart('character', pos_start);
      range.select();
    }
  }
})(jQuery)

Chrome이 frack을 프릭하기 때문에 화살표 키를 사용하는 경우 함수 호출 직후 false를 반환해야합니다.

{
    document.getElementById('moveto3').setSelectionRange(3,3);
    return false;
}

질문을 바탕으로 텍스트 영역에 줄 바꿈이있을 때 대답은 완벽하게 작동하지 않습니다. 대답은 setSelectionRange를 호출하기 전에 지정한 selectionStart, 지정한 selectionEnd을 조정하는 방법을 설명합니다.

@AVProgrammer가 제안한 솔루션으로 다른 질문에서 adjustOffset을 시도해 보았습니다.

function adjustOffset(el, offset) {
    /* From https://stackoverflow.com/a/8928945/611741 */
    var val = el.value, newOffset = offset;
    if (val.indexOf("\r\n") > -1) {
        var matches = val.replace(/\r\n/g, "\n").slice(0, offset).match(/\n/g);
        newOffset += matches ? matches.length : 0;
    }
    return newOffset;
}

$.fn.setCursorPosition = function(position){
    /* From https://stackoverflow.com/a/7180862/611741 */
    if(this.lengh == 0) return this;
    return $(this).setSelection(position, position);
}

$.fn.setSelection = function(selectionStart, selectionEnd) {
    /* From https://stackoverflow.com/a/7180862/611741 
       modified to fit https://stackoverflow.com/a/8928945/611741 */
    if(this.lengh == 0) return this;
    input = this[0];

    if (input.createTextRange) {
        var range = input.createTextRange();
        range.collapse(true);
        range.moveEnd('character', selectionEnd);
        range.moveStart('character', selectionStart);
        range.select();
    } else if (input.setSelectionRange) {
        input.focus();
        selectionStart = adjustOffset(input, selectionStart);
        selectionEnd = adjustOffset(input, selectionEnd);
        input.setSelectionRange(selectionStart, selectionEnd);
    }

    return this;
}

$.fn.focusEnd = function(){
    /* From https://stackoverflow.com/a/7180862/611741 */
    this.setCursorPosition(this.val().length);
}

나는 contenteditable 요소와 jQuery를 위해 이것을 작동시켜야했고 누군가가 그것을 사용할 준비가되기를 강하게했다.

$.fn.getCaret = function(n) {
    var d = $(this)[0];
    var s, r;
    r = document.createRange();
    r.selectNodeContents(d);
    s = window.getSelection();
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return s.anchorOffset;
};

$.fn.setCaret = function(n) {
    var d = $(this)[0];
    d.focus();
    var r = document.createRange();
    var s = window.getSelection();
    r.setStart(d.childNodes[0], n);
    r.collapse(true);
    s.removeAllRanges();
    s.addRange(r);
    console.log('position: '+s.anchorOffset+' of '+s.anchorNode.textContent.length);
    return this;
};

Usage $(selector).getCaret()는 숫자 오프셋을 반환하고 오프셋을 $(selector).setCaret(num)설정하고 요소에 포커스를 설정합니다.

또한 작은 팁 $(selector).setCaret(num)은 콘솔에서 실행 하면 console.log를 반환하지만 콘솔 창에서 설정되므로 포커스를 시각화하지 않습니다.

최고; D


setSelectionRange가 없으면 프로토 타입을 직접 변경할 수 있습니다.

(function() {
    if (!HTMLInputElement.prototype.setSelectionRange) {
        HTMLInputElement.prototype.setSelectionRange = function(start, end) {
            if (this.createTextRange) {
                var range = this.createTextRange();
                this.collapse(true);
                this.moveEnd('character', end);
                this.moveStart('character', start);
                this.select();
            }
        }
    }
})();
document.getElementById("input_tag").setSelectionRange(6, 7);

jsFiddle 링크

참고 URL : https://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area



도와주세요.
반응형