入力フォーカスのテキストを選択


121

テキスト入力があります。入力がフォーカスを受け取ったら、入力内のテキストを選択します。

jQueryでは、次のようにします。

<input type="text" value="test" />
$("input[type=text]").click(function() {
    $(this).select();
    // would select "test" in this example
});

Angularの方法を試してみましたが、見つけたほとんどの例は、モーダルプロパティの変更を監視するディレクティブを処理しています。フォーカスを受け取る入力を監視するディレクティブが必要だと思います。どうすればいいですか?


「角度のある方法」を見つけたいと思っていますが、あなたがやらない理由はあります<input type="text" value="test" onclick="this.select()" />か?
Josef P.

回答:


216

Angularでこれを行う方法は、自動選択を行うカスタムディレクティブを作成することです。

module.directive('selectOnClick', ['$window', function ($window) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function () {
                if (!$window.getSelection().toString()) {
                    // Required for mobile Safari
                    this.setSelectionRange(0, this.value.length)
                }
            });
        }
    };
}]);

次のようにディレクティブを適用します。

<input type="text" value="test" select-on-click />

View demo

Update1:jQuery依存関係を削除しました。

Update2:属性として制限。

Update3:モバイルSafariで動作します。テキストの一部を選択できます(IE> 8が必要です)。


10
jqueryなしでこれを行う場合は、element.clickをelement.bind( 'click'、function(){...}に変更し、element.select()をelement [0] .select()に変更します
jack

3
素敵でエレガント。またrestrict: 'A'、このディレクティブは既存の要素の動作拡張することを目的としているため、ディレクティブを属性として適用することを明示的に制限します(オブジェクトリテラルを返し、を設定します)。
Eliran Malka 14

@Martinユーザーがクリックすることなく、ページを開くときにそれを行う方法はありますか?問題は、デフォルト値が私のselectOnLoadディレクティブlink()の前に別のコントローラーに設定されていることです。しかしlink()では、スコープは既に設定されていますが、要素のDOMはまだ$ scopeと同期されていないため、select()を呼び出しても、要素はまだ空で何も選択されていません。私が見つけた回避策は$ timeoutだけですが、Angularの新しいバージョンでは動作しなくなる可能性があります。
Dzmitry Lazerka、2015年

これはデスクトップ/ Androidでうまく機能しますが、iPadで試してもうまくいかないようです。このあたりに既知の作業はありますか?
ak85 2015年


44

次に、ユーザーがクリックして入力ボックスにカーソルを置いたときにテキストが再選択されないようにする拡張ディレクティブを示します。

module.directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element) {
            var focusedElement;
            element.on('click', function () {
                if (focusedElement != this) {
                    this.select();
                    focusedElement = this;
                }
            });
            element.on('blur', function () {
                focusedElement = null;
            });
        }
    };
})

3
私は名前を変更することを提案している-私はそれが入力されたテキスト内のいくつかの位置にセットカーソルを許可するため、この答えは、より良い受け入れよりもあると思うが、、ディレクティブと独自のスコープを持ってfocusedElementに変数をisElementFocusedが、店舗または
ウラジミールGordienko

2
Uncaught TypeErrorが発生します。undefinedは.select()の「this」の関数ではありません。はい、jQuery 1.9.1が含まれています。
ロビー・スミス

@RobbieSmith私は3年遅れていますが、thistoのすべてのインスタンスを変更element[0]すれば動作するはずです。また、ユーザーが入力をクリックする代わりに入力にタブで移動した場合にテキストが選択されるように変更clickするfocusことをお勧めします。
Lex

40

これは古い回答です、Angular 1.xの場合

それを行うより良い方法は、ng-click組み込みディレクティブを使用することです:

<input type="text" ng-model="content" ng-click="$event.target.select()" />

編集:

以下のようJoshMBは親切に思い出しました。Angular 1.2以降でDOMノードを参照することはできなくなりました。だから、私は$event.target.select()コントローラーに移動しました:

<input type="text" ng-model="content" ng-click="onTextClick($event)" />

次に、コントローラーで:

$scope.onTextClick = function ($event) {
    $event.target.select();
};

これがフィドルです。


2
私の知る限り、これはサポートされていません。Angularは「Angular式でのDOMノードの参照は許可されていません!」というエラーをスローします。詳細については、このスレッドを参照してください:groups.google.com/forum / #!topic / angular / bsTbZ86WAY4。ただし、指令アプローチはうまく機能します。
JoshMB 2014

あなたが正しい。これは、Angular 1.2以降の場合です。答えを更新します。
OnurYıldırım2014年

2
DOMの変更はディレクティブで行われるべきですか?
Piioo 2014年

何らかの理由で他の解決策はうまくいきませんでしたが、うまくいきました。問題は、このクリックイベントを追加する要素にすでにディレクティブがあったことだと思います。
Precastic 2015年

真剣に、今でもonTextClick($ event)がエラーをスローしています。この獣の直感的でない性質は別として、この不便はパフォーマンスにどれほどの負担をかけていますか?
jcalfee314 2015

15

提案された解決策のどちらも私にはうまくいきませんでした。簡単な調査の後、私はこれを思いつきました:

module.directive('selectOnFocus', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var focusedElement = null;

            element.on('focus', function () {
                var self = this;
                if (focusedElement != self) {
                    focusedElement = self;
                    $timeout(function () {
                        self.select();
                    }, 10);
                }
            });

            element.on('blur', function () {
                focusedElement = null;
            });
    }

  }

});

これは提案されているいくつかのソリューションの組み合わせですが、クリックとフォーカスの両方で機能し(オートフォーカスと考えてください)、入力の部分的な値を手動で選択できます。


1
修正された構文エラー:最後}); 置き換え:}}; });
Blackfire、2016

これはinput type = "number"で機能し、素晴らしいです!ありがとう
ルイ

ねえ、これはAndroidではIonicで機能しますが、iOSでは機能しません。ありがとう
Louis

2
あなたがonClickからそれを適応させたとき、あなたはいくつかのコードを残したようです...何の意味がありfocusedElementますか?
Langdon

12

私にとって、ng-clickは意味がありませんでした。すべてのテキストを再度選択しないとカーソルの位置を変えることができなかったため、これは不愉快なことでした。次に、入力がフォーカスされなかった場合にのみテキストが選択されるため、ng-focusを使用することをお勧めします。もう一度クリックしてカーソルを再配置すると、期待どおりにテキストの選択が解除され、その間に書き込むことができます。

私はこのアプローチが期待されるUXの振る舞いであることがわかりました。

ng-focusを使用する

オプション1:別のコード

<input type="text" ng-model="content" ng-focus="onTextFocus($event)" />

そしてコントローラーで

$scope.onTextFocus = function ($event) {
  $event.target.select();
};

オプション2:別の方法として、上記のコードをこの「ワンライナー」に結合できます(これはテストしていませんが、機能するはずです)。

<input type="text" ng-model="content" ng-focus="$event.target.select()" />

シンプルで機能します。これにより、前述のように、選択したテキスト内にカーソルを配置することもできます。
ピストルピート

7

angular 2では、これはChromeとFirefoxの両方で私にとってうまくいきました:

<input type="text" (mouseup)="$event.target.select()">

6

受け入れられた回答はクリックイベントを使用していますが、フォーカスイベントを使用する場合、最初のクリックのみがイベントを発生させ、他のメソッドが入力にフォーカスするために使用されたときにも発生します(タブを押す、コードでフォーカスを呼び出すなど)。

これにより、Tamlynの回答が示唆するように、要素がすでにフォーカスされているかどうかを確認する必要もなくなります。

app.directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('focus', function () {
                this.select();
            });
        }
    };
});

Firefox 38.0.5では、テキストの真ん中をクリックすると、最初にすべてが選択されますが、その後選択が削除されるため、これは機能しません。
user1338062 2015年

1
これはおそらく、遅れることなく一貫して機能することはありませんthis.select
Langdon

6

ディレクティブは必要ありませんonfocus="this.select()"。入力要素またはテキスト領域にネイティブJavaScriptを追加するだけです。


1
最も簡単な方法がここにあるとき、どうしてそんなに多くの人々がこれらすべての複雑な答えを
思いつくの

0

私のために働いた修正バージョン。最初のクリックでテキストを選択し、同じ要素を2回クリックするとテキストの選択を解除します

module.directive('selectOnClick', function ($timeout) {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var prevClickElem = null; //Last clicked element
        var ignorePrevNullOnBlur = false; //Ignoring the prevClickElem = null in Blur massege function

        element.on('click', function () {
            var self = this;
            if (prevClickElem != self) { //First click on new element
                prevClickElem = self; 
                $timeout(function () { //Timer
                    if(self.type == "number")
                        self.select();
                    else
                        self.setSelectionRange(0, self.value.length)
                }, 10);
            }
            else { //Second click on same element
                if (self.type == "number") {
                    ignorePrevNullOnBlur = true;
                    self.blur();
                }
                else
                    self.setSelectionRange(self.value.length, self.value.length); //deselect and set cursor on last pos
            }
        });

        element.on('blur', function () {
            if (ignorePrevNullOnBlur == true)
                ignorePrevNullOnBlur = false; //blur called from code handeling the second click 
            else
                prevClickElem = null; //We are leaving input box
        });
    }
}

})

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