カーソルがJavaScript / jqueryを使用している場所にテキストを挿入する


167

テキストボックスがたくさんあるページがあります。誰かがリンクをクリックしたときに、カーソルのある場所に単語を1つまたは2つ挿入するか、フォーカスがあるテキストボックスに追加します。

たとえば、カーソル/フォーカスが「apple」というテキストボックス上にあり、「[email]」というリンクをクリックした場合、テキストボックスに「apple bob@example.com」と言ってもらいます。

これどうやってするの?ラジオ/ドロップダウン/非テキストボックス要素にフォーカスがある場合はどうなりますか?最後にテキストボックスに焦点を当てたものを覚えられますか?


それはWYSISYGエディターの基礎であるため可能だと思います。その方法はわかりません。
Ian Elliott、


この質問をしていただきありがとうございます。Chrome拡張機能を使用して、カーソルに「[バージョン]」を挿入できます。
haykam

元に戻す機能を備えたシンプルなモジュールを探している場合は、insert-text-textareaを試してください。IE8 +サポートが必要な場合は、insert-text-at-cursorパッケージを試してください
fregante

回答:


241

これをここから使用してください:

function insertAtCaret(areaId, text) {
  var txtarea = document.getElementById(areaId);
  if (!txtarea) {
    return;
  }

  var scrollPos = txtarea.scrollTop;
  var strPos = 0;
  var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
    "ff" : (document.selection ? "ie" : false));
  if (br == "ie") {
    txtarea.focus();
    var range = document.selection.createRange();
    range.moveStart('character', -txtarea.value.length);
    strPos = range.text.length;
  } else if (br == "ff") {
    strPos = txtarea.selectionStart;
  }

  var front = (txtarea.value).substring(0, strPos);
  var back = (txtarea.value).substring(strPos, txtarea.value.length);
  txtarea.value = front + text + back;
  strPos = strPos + text.length;
  if (br == "ie") {
    txtarea.focus();
    var ieRange = document.selection.createRange();
    ieRange.moveStart('character', -txtarea.value.length);
    ieRange.moveStart('character', strPos);
    ieRange.moveEnd('character', 0);
    ieRange.select();
  } else if (br == "ff") {
    txtarea.selectionStart = strPos;
    txtarea.selectionEnd = strPos;
    txtarea.focus();
  }

  txtarea.scrollTop = scrollPos;
}
<textarea id="textareaid"></textarea>
<a href="#" onclick="insertAtCaret('textareaid', 'text to insert');return false;">Click Here to Insert</a>


7
これはうまくいきましたが、すべてのテキストエディターのように、選択したテキストを置き換えることはできません。これは投稿者の元の質問には必要ない場合がありますが、必要な場合は、単に「strPos」を「txtArea.selectionEnd」に置き換えることができます。以下の私の答えは、古いバージョンのIEをサポートする必要がない場合に、ブラウザー検出コードを削除することでこれを示しています。
Jeffrey Harmon

ですべての要素を選択する方法はありますareaIdか?
haykam

1
このような関数を挿入することで、選択したテキストを自動削除できます。function deleteTxt() { var ele = document.getElementById('yourTextarea'); var text = ele.value; text = text.slice(0, ele.selectionStart) + text.slice(ele.selectionEnd); ele.value = text; return text; }
NSTuttle 2016

マウスの位置にテキストを挿入する方法は?
タマライT

あなたは最高です!
Ecko Santoso、

156

短いバージョンかもしれませんが、理解しやすいでしょうか?

    jQuery("#btn").on('click', function() {
        var $txt = jQuery("#txt");
        var caretPos = $txt[0].selectionStart;
        var textAreaTxt = $txt.val();
        var txtToAdd = "stuff";
        $txt.val(textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos) );
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<textarea id="txt" rows="15" cols="70">There is some text here.</textarea>
<input type="button" id="btn" value="OK" />

私はjqueryでポインターの現在の位置からテキストボックスにテキストを追加する方法に応答してこれを書きましたか?


11
:を使用して値を変更した後にキャレット位置を復元することもできますdocument.getElementById("txt").selectionStart = caretPos + txtToAdd.length
Bludwarf 2015

1
おかげで私のために働いた。ちなみに、「selectionStart」プロパティはjqueryセレクター$( "#")を通じて存在しません。document.getElementById()を通過する必要があります
Lego

1
jsfiddle.net/NaHTw/802は、選択した領域を貼り付けたもので置き換えるために少し追加されたソリューションです
patrick

3
まあ、jQueryを削除するのであれば、すべて削除することもできます。; ^)
ルフィン


41

George Claghornからの承認済みの回答は、カーソル位置にテキストを挿入するだけでうまく機能しました。ユーザーがテキストを選択していて、そのテキストを置き換えたい場合(ほとんどのテキストのデフォルトのエクスペリエンス)、 'back'変数を設定するときに小さな変更を加える必要があります。

また、古いバージョンのIEをサポートする必要がない場合、最新バージョンはtextarea.selectionStartをサポートしているため、すべてのブラウザー検出とIE固有のコードを削除できます。

以下は、少なくともChromeとIE11で機能する簡易バージョンで、選択したテキストの置き換えを処理します。

function insertAtCaret(areaId, text) {
    var txtarea = document.getElementById(areaId);
    var scrollPos = txtarea.scrollTop;
    var caretPos = txtarea.selectionStart;

    var front = (txtarea.value).substring(0, caretPos);
    var back = (txtarea.value).substring(txtarea.selectionEnd, txtarea.value.length);
    txtarea.value = front + text + back;
    caretPos = caretPos + text.length;
    txtarea.selectionStart = caretPos;
    txtarea.selectionEnd = caretPos;
    txtarea.focus();
    txtarea.scrollTop = scrollPos;
}

これは適切ですが、要素のmaxlength値は考慮されないため、挿入後の結果の値は最大値よりも長くなる可能性があります。
mbomb007

22

上記のコードは、IEでは機能しませんでした。この回答に基づいたコードを次に示します

getElementById別の方法で要素を参照できるように取り出しました。

function insertAtCaret(element, text) {
  if (document.selection) {
    element.focus();
    var sel = document.selection.createRange();
    sel.text = text;
    element.focus();
  } else if (element.selectionStart || element.selectionStart === 0) {
    var startPos = element.selectionStart;
    var endPos = element.selectionEnd;
    var scrollTop = element.scrollTop;
    element.value = element.value.substring(0, startPos) +
      text + element.value.substring(endPos, element.value.length);
    element.focus();
    element.selectionStart = startPos + text.length;
    element.selectionEnd = startPos + text.length;
    element.scrollTop = scrollTop;
  } else {
    element.value += text;
    element.focus();
  }
}
input{width:100px}
label{display:block;margin:10px 0}
<label for="in2copy">Copy text from: <input id="in2copy" type="text" value="x"></label>
<label for="in2ins">Element to insert: <input id="in2ins" type="text" value="1,2,3" autofocus></label>
<button onclick="insertAtCaret(document.getElementById('in2ins'),document.getElementById('in2copy').value)">Insert</button>

編集:実行中のスニペットが追加されました。jQueryは使用されていません


要素はjqueryオブジェクトですか?element.valueとel​​ement.focus()はどちらも機能しません...
スコットスタッフォード

7
element.focus()DOMElementsでの正当なJavaScriptメソッドです:w3schools.com/jsref/met_html_focus.asp
オリバース

1
最良のアイデアは、IEの互換性を落とすことです。
ar2015

2
ええ、私は7年前にこの答えを書きました。この時点で、IE 11はサポートされている適切な最小バージョンであり、上記のコードはそこで機能します。
コリンアンダーソン

6

@quick_sliv回答を使用:

function insertAtCaret(el, text) {
    var caretPos = el.selectionStart;
    var textAreaTxt = el.value;
    el.value = textAreaTxt.substring(0, caretPos) + text + textAreaTxt.substring(caretPos);
};

4

JQueryとJavaScriptを介してTextBoxの現在のカーソル位置にテキストを挿入する方法

処理する

  1. 現在のカーソル位置を見つける
  2. コピーするテキストを取得する
  3. あそこにテキストをセット
  4. カーソル位置を更新する

ここに2つのTextBoxと1つのボタンがあります。テキストボックスの特定の位置をクリックし、ボタンをクリックして、他のテキストボックスから前のテキストボックスの位置にテキストを貼り付ける必要があります。

ここでの主な問題は、テキストを貼り付ける現在のカーソル位置を取得することです。

//Textbox on which to be pasted
<input type="text" id="txtOnWhichToBePasted" />

//Textbox from where to be pasted
<input type="text" id="txtFromWhichToBePasted" />


//Button on which click the text to be pasted
<input type="button" id="btnInsert" value="Insert"/>


<script type="text/javascript">

$(document).ready(function () {
    $('#btnInsert').bind('click', function () {
            var TextToBePasted = $('#txtFromWhichToBePasted').value;
            var ControlOnWhichToBePasted = $('#txtOnWhichToBePasted');

            //Paste the Text
            PasteTag(ControlOnWhichToBePasted, TextToBePasted);
        });
    });

//Function Pasting The Text
function PasteTag(ControlOnWhichToBePasted,TextToBePasted) {
    //Get the position where to be paste

    var CaretPos = 0;
    // IE Support
    if (document.selection) {

        ControlOnWhichToBePasted.focus();
        var Sel = document.selection.createRange();

        Sel.moveStart('character', -ctrl.value.length);

        CaretPos = Sel.text.length;
    }
    // Firefox support
    else if (ControlOnWhichToBePasted.selectionStart || ControlOnWhichToBePasted.selectionStart == '0')
        CaretPos = ControlOnWhichToBePasted.selectionStart;

    //paste the text
    var WholeString = ControlOnWhichToBePasted.value;
    var txt1 = WholeString.substring(0, CaretPos);
    var txt2 = WholeString.substring(CaretPos, WholeString.length);
    WholeString = txt1 + TextToBePasted + txt2;
    var CaretPos = txt1.length + TextToBePasted.length;
    ControlOnWhichToBePasted.value = WholeString;

    //update The cursor position 
    setCaretPosition(ControlOnWhichToBePasted, CaretPos);
}

function setCaretPosition(ControlOnWhichToBePasted, pos) {

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

</script>

3

現在のカーソル位置にテキストを追加するには、2つの手順が必要です。

  1. 現在のカーソル位置にテキストを追加する
  2. 現在のカーソル位置の更新

デモ:https : //codepen.io/anon/pen/qZXmgN

Chrome 48、Firefox 45、IE 11、およびEdge 25でテスト済み

JS:

function addTextAtCaret(textAreaId, text) {
    var textArea = document.getElementById(textAreaId);
    var cursorPosition = textArea.selectionStart;
    addTextAtCursorPosition(textArea, cursorPosition, text);
    updateCursorPosition(cursorPosition, text, textArea);
}
function addTextAtCursorPosition(textArea, cursorPosition, text) {
    var front = (textArea.value).substring(0, cursorPosition);
    var back = (textArea.value).substring(cursorPosition, textArea.value.length);
    textArea.value = front + text + back;
}
function updateCursorPosition(cursorPosition, text, textArea) {
    cursorPosition = cursorPosition + text.length;
    textArea.selectionStart = cursorPosition;
    textArea.selectionEnd = cursorPosition;
    textArea.focus();    
}

HTML:

<div>
    <button type="button" onclick="addTextAtCaret('textArea','Apple')">Insert Apple!</button>
    <button type="button" onclick="addTextAtCaret('textArea','Mango')">Insert Mango!</button>
    <button type="button" onclick="addTextAtCaret('textArea','Orange')">Insert Orange!</button>
</div>
<textarea id="textArea" rows="20" cols="50"></textarea>

2

次のJavaScriptを使用して、最後にフォーカスしたテキストボックスを追跡できます。

<script>
var holdFocus;

function updateFocus(x)
{
    holdFocus = x;
}

function appendTextToLastFocus(text)
{
    holdFocus.value += text;
}
</script>

使用法:

<input type="textbox" onfocus="updateFocus(this)" />
<a href="#" onclick="appendTextToLastFocus('textToAppend')" />

以前の解決策(gclaghornの小道具)では、textareaを使用してカーソルの位置も計算しているため、必要な場合に適しています。一方、これがあなたが探しているものであれば、これはより軽量になります。


良いアイデア。私はjqueryを使用して、特定のクラスを持つ各テキストボックスにこのイベントを適用したので、各テキストボックスのhtmlに「onfocus = ...」を配置する必要はありませんでした。しかし、良いアプローチです:)
クリックUpvote

1

受け入れられた回答はInternet Explorer 9では機能しませんでした。確認したところ、ブラウザーの検出が適切に機能せず、Internet Explorerでff(firefox)が検出されました。

私はこの変更を行いました:

if ($.browser.msie) 

の代わりに:

if (br == "ie") { 

結果のコードは次のとおりです。

function insertAtCaret(areaId,text) {
    var txtarea = document.getElementById(areaId);
    var scrollPos = txtarea.scrollTop;
    var strPos = 0;
    var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ? 
        "ff" : (document.selection ? "ie" : false ) );

    if ($.browser.msie) { 
        txtarea.focus();
        var range = document.selection.createRange();
        range.moveStart ('character', -txtarea.value.length);
        strPos = range.text.length;
    }
    else if (br == "ff") strPos = txtarea.selectionStart;

    var front = (txtarea.value).substring(0,strPos);  
    var back = (txtarea.value).substring(strPos,txtarea.value.length); 
    txtarea.value=front+text+back;
    strPos = strPos + text.length;
    if (br == "ie") { 
        txtarea.focus();
        var range = document.selection.createRange();
        range.moveStart ('character', -txtarea.value.length);
        range.moveStart ('character', strPos);
        range.moveEnd ('character', 0);
        range.select();
    }
    else if (br == "ff") {
        txtarea.selectionStart = strPos;
        txtarea.selectionEnd = strPos;
        txtarea.focus();
    }
    txtarea.scrollTop = scrollPos;
}


0

必要なテキストボックスにフォーカスし、そこにテキストを挿入することしかできません。焦点がAFAIKである場所を確認する方法はありません(おそらくすべてのDOMノード上で相互作用していますか?)。

このstackoverflowをチェックしてください-それはあなたのための解決策を持っています: どのDOM要素がフォーカスを持っているかをどうやって見つけるのですか?


0

コンテンツ編集可能、HTMLまたはその他のDOM要素の選択

のキャレットに挿入しようとすると<div contenteditable="true">、特に編集可能なコンテナ内に子がある場合、これはさらに困難になります。

私はRangyライブラリを使用して本当に幸運でした:

次のような優れた機能がたくさんあります。

  • 位置または選択を保存
  • その後、位置または選択を復元します
  • 選択HTMLまたはプレーンテキストを取得する
  • 他の多くの間で

私がチェックした最後にオンラインデモは機能していませんでしたが、リポジトリにはデモが機能しています。開始するには、GitまたはNPMからリポジトリをダウンロードし、。/ rangy / demos / index.htmlを開きます。

キャレット位置とテキスト選択の操作が簡単になります。


0

この質問の答えはずっと前に投稿されたので、Google検索で見つけました。HTML5は、setRangeText ()メソッドを含むHTMLInputElement APIを提供します。これは、<input>or <textarea>要素内のテキストの範囲を新しい文字列に置き換えます。

element.setRangeText('abc');

上記は内部elementで行われた選択をに置き換えabcます。入力値のどの部分を置き換えるかを指定することもできます。

element.setRangeText('abc', 3, 5);

上記は、入力値の4番目から6番目の文字をに置き換えますabc。次の文字列のいずれかを4番目のパラメータとして指定することで、テキストを置き換えた後の選択の設定方法を指定することもできます。

  • 'preserve'選択を保存しようとします。これがデフォルトです。
  • 'select' 新しく挿入されたテキストを選択します。
  • 'start' 選択範囲を挿入したテキストの直前に移動します。
  • 'end' 挿入したテキストの直後に選択範囲を移動します。

ブラウザの互換性

setRangeTextのMDNページはブラウザ互換性データを提供しませんが、それは同じだと思います HTMLInputElement.setSelectionRange()。これは、基本的にすべての最新ブラウザーであるIE 9以降、Edge 12以降です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.