web-dev-qa-db-ja.com

Safariで機能しないjQueryを使用したフォーカス上のテキストの選択とChrome

FirefoxとIEで動作する次のjQueryコード( この質問 に似ています)がありますが、ChromeおよびSafari。回避策のアイデアはありますか?

$("#souper_fancy").focus(function() { $(this).select() });
84
user140550

選択が選択解除される原因となっているのはonmouseupイベントであるため、追加するだけです。

$("#souper_fancy").mouseup(function(e){
    e.preventDefault();
});
187
keithnorm
$('#randomfield').focus(function(event) {
    setTimeout(function() {$('#randomfield').select();}, 0);
});
25
Alex0007

これは、input type = "text"要素に対して正常に機能します。 #souper_fancyとはどのような要素ですか?

$("#souper_fancy").focus(function() {
    $(this).select();
});
4
Joe Chung

Mouseupのデフォルトを防止するだけで、テキスト選択は常にオンになります。 MOUSEUPイベントは、テキストの選択をクリアする役割を果たします。ただし、デフォルトの動作を防止することにより、マウスを使用してテキストの選択を解除することはできません。

これを回避し、テキスト選択を再度機能させるには、FOCUSにフラグを設定し、MOUSEUPから読み取り、それをリセットして、将来のMOUSEUPイベントが期待どおりに機能するようにします。

$("#souper_fancy").focus(function() {
    $(this).select();

    //set flag for preventing MOUSEUP event....
    $this.data("preventMouseUp", true);
});

$("#souper_fancy").mouseup(function(e) {
    var preventEvent = $this.data("preventMouseUp");

    //only prevent default if the flag is TRUE
    if (preventEvent) {
        e.preventDefault();
    }

    //reset flag so MOUSEUP event deselect the text
    $this.data("preventMouseUp", false);
});
3
ThiagoPXP

setSelectionRange()へのコールバック内でrequestAnimationFrame()を使用します。

_$(document).on('focus', '._selectTextOnFocus', (e) => {
    var input = e.currentTarget;
    var initialType = e.currentTarget.type;

    requestAnimationFrame(() => {
        // input.select() is not supported on iOS
        // If setSelectionRange is use on a number input in Chrome it throws an exception,
        // so here we switch to type text first.
        input.type = "text";
        input.setSelectionRange(0, Number.MAX_SAFE_INTEGER || 9999);
        input.type = initialType;
    });
});
_

setSelectionRange()はモバイルSafariでは機能しないため、select()の代わりにselect()を使用します( iOSデバイスの入力フィールドのプログラムによる選択(モバイルSafari) )。

テキストを選択する前にrequestAnimationFrameを使用して待機する必要があります。そうしないと、iOSでキーボードが表示された後に要素が正しくスクロールされません。

setSelectionRange()を使用する場合、入力タイプをtextに設定することが重要です。そうしないと、Chrome( selectionStart/selectionEndを参照)入力時にtype = "number"はChromeでは許可されなくなりました )。

1
andrewh

これはIE、Firefox、Chrome、Safari、Operaでの選択には有効ですが、Firefox、Chrome、Safariで2回クリックして編集することはできません。確かではありませんが、フィールドに既にフォーカスがあるにもかかわらず、3つのブラウザーがフォーカスイベントを再発行しているため、実際にカーソルを挿入することはできません(もう一度選択するため)。 IE and Opera実行していないように見えるため、フォーカスイベントが再度発生せず、カーソルが挿入されます。

より良い修正を見つけました このStack postで その問題はなく、すべてのブラウザで動作します。

1
johntrepreneur

SetTimeoutを使用するとちらつきが発生するため、別のイベントベースのソリューションがあります。このように、「フォーカス」イベントは「マウスアップ」イベントをアタッチし、イベントハンドラーは再び自身をデタッチします。

    function selectAllOnFocus(e) {
    if (e.type == "mouseup") { // Prevent default and detach the handler
        console.debug("Mouse is up. Preventing default.");
        e.preventDefault();
        $(e.target).off('mouseup', selectAllOnFocus);
        return;
    }
    $(e.target).select();
    console.debug("Selecting all text");
    $(e.target).on('mouseup', selectAllOnFocus);
}

次に、最初のイベントを配線します

    $('.varquantity').on('focus', selectAllOnFocus);
1
user2941872

これはクロムでも動作するはずです:

$("#souper_fancy").focus(function() {
    var tempSouper = $(this);
    setTimeout(function(){
        tempSouper.select();
    },100);
});
1
rubiwachs

誰かがこの問題に再び出くわした場合、私はここで(現在)すべてのブラウザを含む純粋なJSソリューションを手に入れました。モバイル

<input type="text" value="Hello world..." onFocus="window.setTimeout(() => this.select());">

(setTimeout()なしでは、Safari、モバイルSafari、MS Edgeで動作しません)

0
Claudio