32892


`<input
type="text">`で作成したテキストボックスの`focus`イベントで、Tabキーでフォーカスした場合と、マウスクリックでフォーカスした場合を区別したいです。

## やりたいこと

整数をカンマ区切りで表示するテキストボックスを作ります。  
Excelと同様、フォーカスが入ったらカンマを消し、フォーカスが外れたらカンマを挿入します。  
マウスクリックでフォーカスしたら、カーソルをクリックした位置に設定します（Excel同様、カンマが消えた分、ずれてしまいますが、それは許容します）。  
**Tabキーでフォーカスが入った場合には、テキストボックス内の文字列を全て選択状態** にします。

マウスクリックでは「クリックした位置にカーソルセット」  
Tabキーフォーカスでは「文字列を全選択」  
これは、`<input type="text">`でテキストボックスを作れば、デフォルトでそのように振る舞う、普通の仕様です。

## 問題

フォーカス時にカンマを消す処理は、jQueryを使って

[code]

    var value = $('#text').val().replcae(/,/g, '');
    $('#text').val(value);
    
[/code]

のように処理しています（実際のものとは若干異なりますが、jQueryの`val`メソッドで置換していることは同じで、そこが本質だと思っています）。

ただ、こうすると、テキストボックス内の文字列を選択していても、選択が解除されてしまいます。  
そのため、「もしTabキーによってフォーカスされたら、jQueryの`select`メソッドを呼んで、選択状態にする」という処理を作りたいのです。

何か方法は無いでしょうか？  
同じ目的が達成できれば、別のアプローチでも構いません。


CC BY-SA 3.0
2017-02-23T04:03:03.773
32889
2017-02-23T06:12:50.367
2017-02-23T06:12:50.367
8078
8078
question
javascript jquery
Tabキーによるフォーカスとマウスクリックによるフォーカスを区別したい


最適な手法であるかはさておき、ご質問の内容を実装することは可能です。  
まず表題の「Tabキーによるフォーカスとマウスクリックによるフォーカスを区別したい」という部分ですが、これは標準DOMの[focusイベントオブジェクト](https://developer.mozilla.org/en-
US/docs/Web/Events/focus)に発生要因を示すデータが含まれていないため、focusイベント単体では判定不可能です。ただし、イベントの発生順序がfocus→click/keyupとなっていることを利用して、次に発生するイベントがどちらであるかにより判定可能です。  
つぎに、valueプロパティを書き換えた際に選択が外れてしまう箇所に関しては、[HTMLInputElement.select()](https://developer.mozilla.org/en-
US/docs/Web/API/HTMLInputElement/select)または[HTMLInputElement.setSelectionRange()](https://developer.mozilla.org/en-
US/docs/Web/API/HTMLInputElement/setSelectionRange)メソッドを利用して、選択状態を再設定することで対応可能です。前者は全選択状態に、後者は開始位置、終了位置を指定して選択部分を新たに設定するメソッドで、それぞれの詳細についてはドキュメントなどをご確認ください。  
以下、サンプルではクリックによるフォーカス時にカーソル位置を文字列中央に、キーによるフォーカス時には内容文字列を逆順にして再度全選択する、という動作を実装しています。「カンマを消し…」という動作については理解力不足のためどういう動作が期待されているのか不明でした、コード全体を示していただければ書き換えてみるかもしれません。こちらはご参考までに。

[code]

    const $textbox = document.querySelector("#textbox");
    
    const selectAllContentsOf$textbox = () => $textbox.select();
    const setCursorPositionOf$textbox = pos => $textbox.setSelectionRange(pos, pos);
    
    const $textbox$onFocusdByClick = function (e) {
        console.log('got focus by click');
    
        // move cursor to center
        setCursorPositionOf$textbox(this.value.length / 2);
    };
    const $textbox$onFocusdByKey = function (e) {
        console.log('got focus by key');
    
        // modify value property
        this.value = this.value.split('').reverse().join('');
    
        // then select all content
        selectAllContentsOf$textbox();
    };
    
    $textbox.addEventListener('focus', e => {
        const __onClick = function () {
            $textbox$onFocusdByClick.call($textbox, e);
            $textbox.removeEventListener('keyup', __onKeyup, { once: true });
        };
        const __onKeyup = function () {
            $textbox$onFocusdByKey.call($textbox, e);
            $textbox.removeEventListener('click', __onClick, { once: true });
        };
        $textbox.addEventListener('click', __onClick, { once: true });
        $textbox.addEventListener('keyup', __onKeyup, { once: true });
    });
[/code]

[code]

    <input type="text" value="dummy" />
    <input id="textbox" type="text" value="sample text" />
[/code]


CC BY-SA 3.0
2017-02-23T05:17:40.577
32892
2017-02-23T05:30:27.893
2017-02-23T05:30:27.893
32889
answer