447

jQueryを使用してテキストフィールドのカーソル位置をどのように設定しますか?コンテンツを含むテキストフィールドがあり、ユーザーがフィールドにフォーカスしたときにカーソルを特定のオフセットに配置する必要があります。コードは次のようになります。

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

そのsetCursorPosition関数の実装はどのようになりますか?コンテンツがabcdefgのテキストフィールドがある場合、この呼び出しにより、カーソルは次のように配置されます:abcd ** |**efg。

Javaにも同様の関数setCaretPositionがあります。javascriptにも同様の方法がありますか?

更新:次のように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);
4

16 に答える 16

302

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
于 2009-05-08T18:17:32.917 に答える
263

私には2つの機能があります:

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 からの使用を示す、 atextareaと an の両方を使用した実際の例: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 をサポートしていません)。

于 2009-01-31T16:56:36.723 に答える
38

ここでのソリューションは、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;
};
于 2010-09-06T11:55:41.480 に答える
25

私は私のために働く解決策を見つけました:

$.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.
于 2011-08-24T19:02:59.703 に答える
14

これは、Mac OSX、jQuery 1.4 の Safari 5 で機能しました。

$("Selector")[elementIx].selectionStart = desiredStartPos; 
$("Selector")[elementIx].selectionEnd = desiredEndPos;
于 2010-08-26T15:51:17.987 に答える
10

これが非常に古い投稿であることは認識していますが、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) が機能しないため、後でこれを編集して、その部分が再び機能することを確認する必要があります。それを行う方法についてアイデアがある場合は、ここにコメントしてください。喜んでテストします。ありがとう。

于 2015-12-03T20:44:04.920 に答える
8

テキストエリアにテキストを挿入する前にフォーカスを設定しますか?

$("#comments").focus();
$("#comments").val(comments);
于 2013-01-01T09:38:49.293 に答える
8

IE でカーソルを特定の位置に移動するには、次のコードで十分です。

var range = elt.createTextRange();
range.move('character', pos);
range.select();
于 2009-05-14T13:12:48.197 に答える
8

私はこれを使用しています: http://plugins.jquery.com/project/jCaret

于 2010-01-18T20:20:29.740 に答える
7

これはクロムで私にとってはうまくいきます

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

どうやら、マイクロ秒以上の遅延が必要なようです。通常、ユーザーは、オーバーライドしたいテキスト フィールド内の位置をクリックする (またはタブを押す) ことによってテキスト フィールドにフォーカスするため、位置が変更されるまで待たなければならないからです。ユーザーがクリックして設定し、変更します。

于 2015-06-27T23:16:04.507 に答える
4

矢印キーを使用している場合は、関数呼び出しの直後にfalseを返すことを忘れないでください。そうしないと、Chromeが破砕します。

{
    document.getElementById('moveto3').setSelectionRange(3,3);
    return false;
}
于 2011-03-08T01:41:34.770 に答える
4

この質問に基づいて、テキストエリアに新しい行がある場合、ie とオペラでは答えが完全に機能しません。答えは、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);
}
于 2012-02-02T17:08:00.740 に答える
4

bitbucketで見つけたコードの小さな変更

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)
于 2012-04-11T05:52:27.013 に答える
1

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リンク

于 2011-10-17T07:44:50.177 に答える