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>