web-dev-qa-db-ja.com

タブを使用してテキストエリアでインデントする

私の側にはシンプルなhtmlテキストエリアがあります。現在、タブをクリックすると、次のフィールドに移動します。代わりに、タブボタンにいくつかのスペースをインデントさせたいと思います。これどうやってするの?ありがとう。

132
user780483

同様の質問に対する他の回答から大きく借用(以下に投稿)...

$(document).delegate('#textbox', 'keydown', function(e) {
  var keyCode = e.keyCode || e.which;

  if (keyCode == 9) {
    e.preventDefault();
    var start = this.selectionStart;
    var end = this.selectionEnd;

    // set textarea value to: text before caret + tab + text after caret
    $(this).val($(this).val().substring(0, start)
                + "\t"
                + $(this).val().substring(end));

    // put caret at right position again
    this.selectionStart =
    this.selectionEnd = start + 1;
  }
});

jQuery:Textbox内でTabキーを押す方法をキャプチャする方法

textareaで<tab>を処理する方法

http://jsfiddle.net/jz6J5/

113
kasdega
var textareas = document.getElementsByTagName('textarea');
var count = textareas.length;
for(var i=0;i<count;i++){
    textareas[i].onkeydown = function(e){
        if(e.keyCode==9 || e.which==9){
            e.preventDefault();
            var s = this.selectionStart;
            this.value = this.value.substring(0,this.selectionStart) + "\t" + this.value.substring(this.selectionEnd);
            this.selectionEnd = s+1; 
        }
    }
}

このソリューションはjQueryを必要とせず、ページ上のすべてのテキスト領域でタブ機能を有効にします。

49
user1949974

他の人が書いたように、JavaScriptを使用してイベントをキャプチャし、デフォルトのアクションを防止して(カーソルがフォーカスを移動しないように)、タブ文字を挿入できます。

ただし、デフォルトの動作を無効にすると、マウスを使用せずにテキスト領域からフォーカスを移動できなくなります。目の不自由なユーザーは、キーボードを使用してWebページを操作しますが、マウスポインターが表示されないため、キーボードを使用するか、何も使用しません。タブキーは、ドキュメント、特にフォームをナビゲートする主な方法です。タブキーのデフォルトの動作をオーバーライドすると、目の不自由なユーザーが次のフォーム要素にフォーカスを移動することができなくなります。

したがって、幅広い読者向けのWebサイトを作成している場合は、compelling理由なし​​でこれを行うことをお勧めします。テキストエリアにそれらをトラップしない盲目のユーザーのための代替。

37
Will Martin

価値のあることについては、このスレッドで皆さんが話していることについて、私のonelinerがあります。

<textarea onkeydown="if(event.keyCode===9){var v=this.value,s=this.selectionStart,e=this.selectionEnd;this.value=v.substring(0, s)+'\t'+v.substring(e);this.selectionStart=this.selectionEnd=s+1;return false;}">
</textarea>

Chrome、Firefox、Internet Explorer、Edgeの最新版でテストされています。

31
elgholm

両方が簡単で、最後の変更を元に戻す(Ctrl + Z))能力を失わない最新の方法。

$('#your-textarea').keydown(function (e) {
    var keyCode = e.keyCode || e.which;

    if (keyCode === $.ui.keyCode.TAB) {
        e.preventDefault();

        const TAB_SIZE = 4;

        // The one-liner that does the magic
        document.execCommand('insertText', false, ' '.repeat(TAB_SIZE));
    }
});

execCommandの詳細:

8
Yom S.

これが私のバージョンです、サポートしています:

  • タブ+シフトタブ
  • 単純なタブ文字挿入のために元に戻すスタックを維持します
  • ブロック行のインデント/インデント解除をサポートしますが、スタックを元に戻します
  • ブロックのインデント/インデント解除時に行全体を適切に選択する
  • enterキーを押すと自動インデントをサポートします(アンドゥスタックを維持します)
  • 次のタブでエスケープキーキャンセルサポートを使用する/ Enterキー(したがって、エスケープキーを押してからタブアウトすることができます)
  • Chrome + Edgeで動作し、テストされていない他のユーザー。
$(function() { 
        var enabled = true;
        $("textarea.tabSupport").keydown(function(e) {

                // Escape key toggles tab on/off
                if (e.keyCode==27)
                {
                        enabled = !enabled;
                        return false;
                }

                // Enter Key?
                if (e.keyCode === 13 && enabled)
                {
                        // selection?
                        if (this.selectionStart == this.selectionEnd)
                        {
                                // find start of the current line
                                var sel = this.selectionStart;
                                var text = $(this).val();
                                while (sel > 0 && text[sel-1] != '\n')
                                sel--;

                                var lineStart = sel;
                                while (text[sel] == ' ' || text[sel]=='\t')
                                sel++;

                                if (sel > lineStart)
                                {
                                        // Insert carriage return and indented text
                                        document.execCommand('insertText', false, "\n" + text.substr(lineStart, sel-lineStart));

                                        // Scroll caret visible
                                        this.blur();
                                        this.focus();
                                        return false;
                                }
                        }
                }

                // Tab key?
                if(e.keyCode === 9 && enabled) 
                {
                        // selection?
                        if (this.selectionStart == this.selectionEnd)
                        {
                                // These single character operations are undoable
                                if (!e.shiftKey)
                                {
                                        document.execCommand('insertText', false, "\t");
                                }
                                else
                                {
                                        var text = this.value;
                                        if (this.selectionStart > 0 && text[this.selectionStart-1]=='\t')
                                        {
                                                document.execCommand('delete');
                                        }
                                }
                        }
                        else
                        {
                                // Block indent/unindent trashes undo stack.
                                // Select whole lines
                                var selStart = this.selectionStart;
                                var selEnd = this.selectionEnd;
                                var text = $(this).val();
                                while (selStart > 0 && text[selStart-1] != '\n')
                                        selStart--;
                                while (selEnd > 0 && text[selEnd-1]!='\n' && selEnd < text.length)
                                        selEnd++;

                                // Get selected text
                                var lines = text.substr(selStart, selEnd - selStart).split('\n');

                                // Insert tabs
                                for (var i=0; i<lines.length; i++)
                                {
                                        // Don't indent last line if cursor at start of line
                                        if (i==lines.length-1 && lines[i].length==0)
                                                continue;

                                        // Tab or Shift+Tab?
                                        if (e.shiftKey)
                                        {
                                                if (lines[i].startsWith('\t'))
                                                        lines[i] = lines[i].substr(1);
                                                else if (lines[i].startsWith("    "))
                                                        lines[i] = lines[i].substr(4);
                                        }
                                        else
                                                lines[i] = "\t" + lines[i];
                                }
                                lines = lines.join('\n');

                                // Update the text area
                                this.value = text.substr(0, selStart) + lines + text.substr(selEnd);
                                this.selectionStart = selStart;
                                this.selectionEnd = selStart + lines.length; 
                        }

                        return false;
                }

                enabled = true;
                return true;
        });
});
textarea
{
  width: 100%;
  height: 100px;
  tab-size: 4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea class="tabSupport">if (something)
{
        // This textarea has "tabSupport" CSS style
        // Try using tab key
        // Try selecting multiple lines and using tab and shift+tab
        // Try pressing enter at end of this line for auto indent
        // Use Escape key to toggle tab support on/off
        //     eg: press Escape then Tab to go to next field
}
</textarea>
<textarea>This text area doesn't have tabSupport class so disabled here</textarea>
6
Brad Robinson

@kasdegaソリューションに基づく複数行のインデントスクリプト。

$('textarea').on('keydown', function (e) {
    var keyCode = e.keyCode || e.which;

    if (keyCode === 9) {
        e.preventDefault();
        var start = this.selectionStart;
        var end = this.selectionEnd;
        var val = this.value;
        var selected = val.substring(start, end);
        var re = /^/gm;
        var count = selected.match(re).length;


        this.value = val.substring(0, start) + selected.replace(re, '\t') + val.substring(end);
        this.selectionStart = start;
        this.selectionEnd = end + count;
    }
});
6
Martin

TABキーを押してスペースを挿入するには、JSコードを記述する必要があります。 JSFiddleの機能に似たもの。

Jquery fiddle を確認してください:

HTML

<textarea id="mybox">this is a test</textarea>

JavaScript

$('#mybox').live('keydown', function(e) { 
  var keyCode = e.keyCode || e.which; 

  if (keyCode == 9) { 
    e.preventDefault(); 
    alert('tab pressed');
  } 
});
​
6
Aziz Shaikh

このソリューションを使用すると、一般的なコードエディターのように選択範囲全体をタブで移動したり、その選択を解除したりできます。ただし、選択範囲がない場合にshift-tabを実装する方法はわかりません。

$('#txtInput').on('keydown', function(ev) {
    var keyCode = ev.keyCode || ev.which;

    if (keyCode == 9) {
        ev.preventDefault();
        var start = this.selectionStart;
        var end = this.selectionEnd;
        var val = this.value;
        var selected = val.substring(start, end);
        var re, count;

        if(ev.shiftKey) {
            re = /^\t/gm;
            count = -selected.match(re).length;
            this.value = val.substring(0, start) + selected.replace(re, '') + val.substring(end);
            // todo: add support for shift-tabbing without a selection
        } else {
            re = /^/gm;
            count = selected.match(re).length;
            this.value = val.substring(0, start) + selected.replace(re, '\t') + val.substring(end);
        }

        if(start === end) {
            this.selectionStart = end + count;
        } else {
            this.selectionStart = start;
        }

        this.selectionEnd = end + count;
    }
});
#txtInput {
  font-family: monospace;
  width: 100%;
  box-sizing: border-box;
  height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<textarea id="txtInput">
$(document).ready(function(){
        $("#msgid").html("This is Hello World by JQuery");
});
</textarea>
6
mpen

人々が答えについてここで言わなければならなかったすべてに基づいて、キーダウン(キーアップではなく)+ preventDefault()+キャレットにタブ文字を挿入するだけの組み合わせです。何かのようなもの:

var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
   e.preventDefault();
   insertAtCaret('txt', '\t')
}

以前の回答にはjsfiddleが機能していましたが、キーダウン時にalert()を使用していました。このアラートを削除すると、機能しませんでした。テキストエリアの現在のカーソル位置にタブを挿入する関数を追加しました。

同じもののjsfiddleが動作しています: http://jsfiddle.net/nsHGZ/

3
walmik

この問題は解決されていません。これをコーディングしましたが、非常にうまく機能しています。カーソルインデックスに表を挿入します。 jqueryを使用せずに

<textarea id="myArea"></textarea>
<script>
document.getElementById("myArea").addEventListener("keydown",function(event){
    if(event.code==="Tab"){
        var cIndex=this.selectionStart;
        this.value=[this.value.slice(0,cIndex),//Slice at cursor index
            "\t",                              //Add Tab
            this.value.slice(cIndex)].join('');//Join with the end
        event.stopPropagation();
        event.preventDefault();                //Don't quit the area
        this.selectionStart=cIndex+1;
        this.selectionEnd=cIndex+1;            //Keep the cursor in the right index
    }
});
</script>
2
Bibimission

Altキーを押しながら、テンキーの0,9を押します。 google-chromeで動作します

2
krishna

上記はすべてのワイプのアンドゥ履歴に答えます。それをしない解決策を探している人のために、私は最後の時間をChromeのために以下をコーディングすることに費やしました:

jQuery.fn.enableTabs = function(TAB_TEXT){
    // options
    if(!TAB_TEXT)TAB_TEXT = '\t';
    // text input event for character insertion
    function insertText(el, text){
        var te = document.createEvent('TextEvent');
        te.initTextEvent('textInput', true, true, null, text, 9, "en-US");
        el.dispatchEvent(te);
    }
    // catch tab and filter selection
    jQuery(this).keydown(function(e){
        if((e.which || e.keyCode)!=9)return true;
        e.preventDefault();
        var contents = this.value,
            sel_start = this.selectionStart,
            sel_end = this.selectionEnd,
            sel_contents_before = contents.substring(0, sel_start),
            first_line_start_search = sel_contents_before.lastIndexOf('\n'),
            first_line_start = first_line_start_search==-1 ? 0 : first_line_start_search+1,
            tab_sel_contents = contents.substring(first_line_start, sel_end),
            tab_sel_contents_find = (e.shiftKey?new RegExp('\n'+TAB_TEXT, 'g'):new RegExp('\n', 'g')),
            tab_sel_contents_replace = (e.shiftKey?'\n':'\n'+TAB_TEXT);
            tab_sel_contents_replaced = (('\n'+tab_sel_contents)
                .replace(tab_sel_contents_find, tab_sel_contents_replace))
                .substring(1),
            sel_end_new = first_line_start+tab_sel_contents_replaced.length;
        this.setSelectionRange(first_line_start, sel_end);
        insertText(this, tab_sel_contents_replaced);
        this.setSelectionRange(first_line_start, sel_end_new);
    });
};

つまり、選択した行の先頭にタブが挿入されます。

JSFiddle: http://jsfiddle.net/iausallc/5Lnabspr/11/

要点: https://Gist.github.com/iautomation/e53647be326cb7d7112d

使用例:$('textarea').enableTabs('\t')

短所:そのままChromeでのみ機能します。

1
iautomation

最も簡単な方法私はそれを行うことがわかった最新のブラウザでVanilla JavaScriptである:

  <textarea name="codebox"></textarea>
  
  <script>
  const codebox = document.querySelector("[name=codebox]")

  codebox.addEventListener("keydown", (e) => {
    let { keyCode } = e;
    let { value, selectionStart, selectionEnd } = codebox;

    if (keyCode === 9) {  // TAB = 9
      e.preventDefault();

      codebox.value = value.slice(0, selectionStart) + "  " + value.slice(selectionEnd);

      codebox.setSelectionRange(selectionStart+2, selectionStart+2)
    }
  });
  </script>

簡単にするために、このスニペットで多くのES6機能を使用したことに注意してください。展開する前に、おそらく(BabelまたはTypeScriptで)トランスパイルする必要があります。

0
Telmo Trooper

好きなtextarea要素でアクセスできるものを作成しました:

function textControl (element, event)
{
    if(event.keyCode==9 || event.which==9)
    {
        event.preventDefault();
        var s = element.selectionStart;
        element.value = element.value.substring(0,element.selectionStart) + "\t" + element.value.substring(element.selectionEnd);
        element.selectionEnd = s+1; 
    }
}

要素は次のようになります。

<textarea onkeydown="textControl(this,event)"></textarea>
0
Hellena Bailey