代码之家  ›  专栏  ›  技术社区  ›  jcnnghm

jQuery在文本区域中设置光标位置

  •  426
  • jcnnghm  · 技术社区  · 16 年前

    如何使用jQuery设置文本字段中的光标位置?我有一个包含内容的文本字段,我希望用户在关注该字段时将光标定位在某个偏移位置。代码应该是这样的:

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

    Java有一个类似的函数,setCaretPosition。javascript是否存在类似的方法?

    更新:我修改了CMS的代码以使用jQuery,如下所示:

    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);
    
    15 回复  |  直到 11 年前
        1
  •  302
  •   Web_Designer    9 年前

    下面是一个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
    
        2
  •  262
  •   T.J. Crowder    9 年前

    我有两个职能:

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

    然后您可以像这样使用SetCareTopos:

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

    textarea input ,显示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);
    }
    
    $("#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上进行了测试和工作(见最后一页) here ; 堆栈代码段不支持IE8)。

        3
  •  37
  •   HRJ    14 年前

    扩展函数应该迭代每个选定的元素并返回 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;
    };
    
        4
  •  24
  •   José Veríssimo    5 年前

    我找到了一个适合我的解决方案:

    $.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.
    
        5
  •  12
  •   BobFromBris    14 年前

    $("Selector")[elementIx].selectionStart = desiredStartPos; 
    $("Selector")[elementIx].selectionEnd = desiredEndPos;
    
        6
  •  9
  •   tofirius    9 年前

    我确实意识到这是一篇非常古老的文章,但我认为我应该提供一个更简单的解决方案,只使用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;
    }
    

    $('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)工作,因此我必须在将来编辑此解决方案,以确保零件再次工作。如果你有一个如何做到这一点的想法,请在这里发表评论,我会很高兴地测试出来。谢谢

        7
  •  7
  •   Kirilloid Kirilloid    16 年前

    var range = elt.createTextRange();
    range.move('character', pos);
    range.select();
    
        8
  •  7
  •   Ben Noland    15 年前
        9
  •  7
  •   Steven Whitby    12 年前

    在将文本插入文本区域之前设置焦点,是这样吗?

    $("#comments").focus();
    $("#comments").val(comments);
    
        10
  •  6
  •   Hung Tran    10 年前

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

    显然,您需要一微秒或更长的延迟,因为通常用户通过单击文本字段中要覆盖的某个位置(或通过点击tab)来聚焦文本字段,因此您必须等待用户单击设置位置,然后更改它。

        11
  •  4
  •   erich    14 年前

    如果您使用的是箭头键,请记住在函数调用后立即返回false,否则Chrome会损坏分形。

    {
        document.getElementById('moveto3').setSelectionRange(3,3);
        return false;
    }
    
        12
  •  4
  •   Community CDub    8 年前

    基于此, question ,当文本区域中出现新行时,答案不会完全适用于ie和opera。 answer 在调用setSelectionRange之前,解释如何调整selectionStart、selectionEnd。

    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);
    }
    
        13
  •  4
  •   twig    13 年前

    对我在中找到的代码的小修改 bitbucket

    如果给定2个位置,代码现在可以选择/突出显示起点/终点。

    $('#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)
    
        14
  •  3
  •   FGZ    8 年前

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

    用法 $(selector).getCaret() 返回偏移量和 $(selector).setCaret(num) 建立offset并将焦点设置在元素上。

    如果你跑步的话,还有一个小提示 $(选择器).setCaret(num)

    最好的;D

        15
  •  1
  •   Anoop    13 年前

    如果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 链接

        16
  •  0
  •   David Buck Richard Ferris    4 年前

    $('#text').keyup(function () {
        var cursor = $('#text').prop('selectionStart');
        //if cursot is first in textarea
        if (cursor == 0) {
            //i will add tab in line
            $('#text').val('\t' + $('#text').val());
            //here we set the cursor position
            $('#text').prop('selectionEnd', 1);
        } else {
            var value = $('#text').val();
            //save the value before cursor current position
            var valToCur = value.substring(0, cursor);
            //save the value after cursor current position
            var valAfter = value.substring(cursor, value.length);
            //save the new value with added tab in text
            $('#text').val(valToCur + '\t' + valAfter);
            //set focus of cursot after insert text (1 = because I add only one symbol)
            $('#text').prop('selectionEnd', cursor + 1);
        }
    });