Edited at

[JS] Tabキーによる移動を禁止してTabを入力する。

More than 1 year has passed since last update.


Update


  • 2018/01/10 14:59

    @hoo-chan さんにご提示頂いたコードを元に再構成。

    コードは解説が要らないくらいシンプル&スマートに。

    元記事は「出来の悪い元記事」として残します。



やりたいこと


  • テキストエリアやテキストボックスで、タブを入力したい。


スニペット


javascript


// element: Tabを入力できるようにしたい要素
element.addEventListener("keydown", input_tab);

function input_tab(event) {
if (event.key === "Tab") {
// デフォルト動作停止
event.preventDefault();
// Tabを挿入。範囲指定時は置換。
var TAB = "\t";
var value = this.value;
var sPos = this.selectionStart;
var ePos = this.selectionEnd;
var result = value.slice(0, sPos) + TAB + value.slice(ePos);
var cPos = sPos + TAB.length;
this.value = result;
this.setSelectionRange(cPos, cPos);
}
}


tabの挿入には setRangeText() を使うと更に簡単に書けますが、現状IE/Edgeが未対応であるため、今回は使用しない方法で記載します。


サンプル


sample.html

<html>

<head>
</head>
<body>
▼タブで移動<br>
<textarea rows=3 cols=40></textarea><br>
<input type=text>
<input type=password>
<br>
<br>
▼タブ入力可(タブでの移動禁止)<br>
<textarea rows=3 cols=40 class="tab_input"></textarea><br>
<input type=text class="tab_input">
<input type=password class="tab_input">

<script>
// Tabを入力できるようにしたい要素
var elements = document.getElementsByClassName("tab_input");
for ( var i = 0; i < elements.length; i++ ){
elements[i].addEventListener("keydown", input_tab);
}

function input_tab(event) {
if (event.key === "Tab") {
// デフォルト動作停止
event.preventDefault();
// タブを挿入。範囲指定時は置換。
var TAB = "\t";
var value = this.value;
var sPos = this.selectionStart;
var ePos = this.selectionEnd;
var result = value.slice(0, sPos) + TAB + value.slice(ePos);
var cPos = sPos + TAB.length;
this.value = result;
this.setSelectionRange(cPos, cPos);
}
}
</script>
</body>
</html>



出来の悪い元記事


スニペット


javascript

function tab_input(element){

// フォーカスイン
element.addEventListener("focus", function(event) {
// Tabキーの挙動をフォーカス移動ではなくタブ入力にする。
window.document.onkeydown = function(event){
// 9 = Tab
if(event.keyCode === 9) {
// デフォルト動作停止
event.preventDefault();

// Tabを挿入。範囲指定時は置換。
var obj = event.target; // オブジェクト取得
var sPos = obj.selectionStart; // 入力(選択)開始位置
var ePos = obj.selectionEnd; // 入力(選択)終了位置
var result = obj.value.substr(0, sPos) + "\t" + obj.value.substr(ePos);
obj.value = result;

// 入力したタブの後ろを選択。
var cPos = sPos + "\t".length;
obj.setSelectionRange(cPos, cPos);
}
};
},false);

// フォーカスアウト
element.addEventListener("blur", function(event) {
// デフォルト動作を行うように再設定
window.document.onkeydown = function(event){
return true;
};
},false);
}



簡単に解説


  • まず、Tabキーによるコントロールの移動を禁止する。

    window.document.onkeydown イベントの処理でタブキーが押された時に event.preventDefault(); を実行して、デフォルト動作をしないよう設定する。

  • だがそれだけでは影響範囲が「ページ上の全てのコントロール」になってしまう。

    対象となるコントロールを限定するため以下のようにする。


    • 対象コントロールにフォーカスインしたら window.document.onkeydown のイベント処理を登録。

    • 対象コントロールからフォーカスアウトしたらイベント処理を解放。



  • Tabを入力する処理については特記事項なし。


サンプル


sample.html

<html>

<head>
</head>
<body>
▼タブで移動<br>
<textarea rows=3 cols=40></textarea><br>
<input type=text>
<input type=password>
<br>
<br>
▼タブ入力可(タブでの移動禁止)<br>
<textarea rows=3 cols=40 class="tab_input"></textarea><br>
<input type=text class="tab_input">
<input type=password class="tab_input">

<script>
// "tab_input"クラスが設定されているコントロールを対象として設定
let elements = document.getElementsByClassName("tab_input");
for( let element of elements ){
tab_input(element);
}

function tab_input(element){
// フォーカスイン
element.addEventListener("focus", function(event) {
// タブキーの挙動をフォーカス移動ではなくタブ入力にする。
window.document.onkeydown = function(event){
// 9 = Tab
if(event.keyCode === 9) {
// デフォルト動作停止
event.preventDefault();

// タブを挿入。範囲指定時は置換。
var obj = event.target; // オブジェクト取得
var sPos = obj.selectionStart; // 入力(選択)開始位置
var ePos = obj.selectionEnd; // 入力(選択)終了位置
var result = obj.value.substr(0, sPos) + "\t" + obj.value.substr(ePos);
obj.value = result;

// 入力したタブの後ろを選択。
var cPos = sPos + "\t".length;
obj.setSelectionRange(cPos, cPos);
}
};
},false);

// フォーカスアウト
element.addEventListener("blur", function(event) {
// デフォルト動作を行うように再設定
window.document.onkeydown = function(event){
return true;
};
},false);
}
</script>
</body>
</html>