web-dev-qa-db-ja.com

テキスト領域のjQueryセットアップカーソール位置

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);
429
jcnnghm

私は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からの使用法を示す、textareainputの両方を含むライブ例

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をサポートしていません)。

251
CMS

これが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
294
mpen

ここでの解決策は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;
};
37
HRJ

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

$.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;
    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();
22
AVProgrammer

これは私にとってMac OSX上のSafari 5、jQuery 1.4でうまくいきました。

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

これは非常に古い投稿であることを私は認識していますが、私はおそらく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)が機能することを可能にしないので、その部分が再び機能することを確かめるために将来これを編集しなければならないでしょう。その方法をご存知の場合は、ここにコメントしてください。ぜひ試してみてください。ありがとう。

7
tofirius

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

7
Ben Noland

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

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

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

$("#comments").focus();
$("#comments").val(comments);
6
Steven Whitby

これは私にとってクロムで働きます

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

マイクロ秒以上の遅延が必要なのは明らかです。通常、ユーザーはオーバーライドしたいテキストフィールド内の任意の位置をクリックして(またはタブを押して)テキストフィールドにフォーカスを合わせるため、その位置になるまで待つ必要があるユーザーがクリックして設定します。

5
Hung Tran

私が 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)
4
twig

Chromeはそれ以外の場合は問題を解決するため、矢印キーを使用している場合は、関数呼び出しの直後にfalseを返すようにしてください。

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

この 質問 に基づいて、テキストエリアに新しい行があると、答えは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);
}
3
Ghislain Hivon

私はこれを満足のいく要素と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;
};

使用法$(selector).getCaret()は数値オフセットを返し、$(selector).setCaret(num)はオフセットを設定し、要素にフォーカスを設定します。

ちょっとしたコツ、コンソールから$(selector).setCaret(num)を実行した場合、console.logが返されますが、フォーカスはコンソールウィンドウで確立されるため視覚化されません。

ベスト、D

2
FGZ

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

1
Anoop