web-dev-qa-db-ja.com

Chromeフォーカスバグを選択する]のより良い回避策を探しています

この質問 のユーザーと同じ問題があります。これはWebkitの このバグ が原因です。ただし、提供されている回避策は私のアプリでは機能しません。別の質問を読む必要がないように、問題を言い直します。

フォーカスがかかったときに、テキストエリア内のすべてのテキストを選択しようとしています。次のjQueryコードはIE/FF/Operaで機能します。

$('#out').focus(function(){
  $('#out').select();
});

ただし、Chrome/Safariでは、テキストが非常に短時間選択されますが、その後、mouseUpイベントが発生し、テキストの選択が解除されます。上記のリンクでは、次の回避策が提供されています。

$('#out').mouseup(function(e){
  e.preventDefault();
});

ただし、この回避策は私には良くありません。ユーザーがtextareaにフォーカスを与えたときに、すべてのテキストのみを選択したい。彼は、選択した場合、テキストの一部のみを選択できる必要があります。誰かがまだこの要件を満たしている回避策を考えることができますか?

36
Jenni

これはどう?

$('#out').focus(function () {
    $('#out').select().mouseup(function (e) {
        e.preventDefault();
        $(this).unbind("mouseup");
    });
});
29
tcooc

受け入れられた答え(そして基本的に私がこれまでに見つけた他のすべての解決策)は、キーボードフォーカスでは機能しません。 e。少なくとも私のChromium21ではタブを押します。代わりに次のスニペットを使用します。

_$('#out').focus(function () {
  $(this).select().one('mouseup', function (e) {
    $(this).off('keyup');
    e.preventDefault();
  }).one('keyup', function () {
    $(this).select().off('mouseup');
  });
});
_

keyupまたはfocusハンドラーのe.preventDefault()は役に立たないため、キーボードフォーカス後の選択解除は、デフォルトハンドラーでは発生せず、focusイベントとkeyupイベントの間のどこかで発生するようです。

@BarelyFitzが示唆しているように、他のイベントハンドラーを誤ってバインド解除しないように、名前空間付きイベントを操作する方がよい場合があります。そのためには、_'keyup'_を_'keyup.selectText'_に、_'mouseup'_を_'mouseup.selectText'_に置き換えます。

25
Adrian Heine

単純にしない理由:

$('#out').focus(function(){
    $(this).one('mouseup', function() {
        $(this).select();
    });
});

すべての主要なブラウザで動作するようです...

3
Barbarab

非常にわずかに異なるアプローチは、フォーカスイベントをマウスシーケンスから分離することです。これは私にとって非常にうまく機能します-状態変数、リークされたハンドラー、ハンドラーの不注意な削除はなく、クリック、タブ、またはプログラムフォーカスで機能します。以下のコードとjsFiddle-

$('#out').focus(function() {
    $(this).select();
});
$('#out').on('mousedown.selectOnFocus', function() {
    if (!($(this).is(':focus'))) {
        $(this).focus();
        $(this).one('mouseup.selectOnFocus', function(up) {
            up.preventDefault();
        });
    }
});

https://jsfiddle.net/tpankake/eob9eb26/27/

2
tpankake

入力ボックスにフォーカスを置く前に、テキストを選択してください。

$('#out').select().focus();
2
finpup

boolを作成します。フォーカスイベントの後でtrueに設定し、マウスアップイベントの後でリセットします。マウスを上に向けているときにtrueの場合、ユーザーがテキストフィールドを選択したことがわかります。したがって、マウスアップが発生しないようにする必要があることがわかります。それ以外の場合は、通過させる必要があります。

var textFieldGotFocus = false;

$('#out').focus(function()
{
    $('#out').select();
    textFieldGotFocus = true;
});

$('#out').mouseup(function(e)
{
    if (textFieldGotFocus)
        e.preventDefault();
});

$(document).mouseup(function() { textFieldGotFocus = false; });

変数をリセットするmouseupリスナーをdocumentに配置することが重要です。これは、ユーザーがテキストフィールド上でマウスボタンを離すことが保証されていないためです。

2
zneak
onclick="var self = this;setTimeout(function() {self.select();}, 0);"
1
Terje

tpankakeの回答は再利用可能なjQuery関数に変換されました。
(これに賛成する場合は、彼の回答にも賛成してください)

jQueryライブラリをロードした後に以下をロードします:

$.fn.focusSelect = function () {
    return this.each(function () {
        var me = $(this);
        me.focus(function () {
            $(this).select();
        });
        me.on('mousedown.selectOnFocus', function () {
            var me2 = $(this);
            if (me2.is(':focus') === false) {
                me2.focus();
                me2.one('mouseup.selectOnFocus', function (up) {
                    up.preventDefault();
                });
            }
        });
    });
};

このように使用してください:

$(document).ready(function () {
    // apply to all inputs on the page:
    $('input[type=text]').focusSelect();

    // apply only to one input
    $('#out').focusSelect();
});
0
Drew

digitalfreshのソリューションはほとんどありますが、JSを使用して(クリックを使用せずに)手動で.focus()をトリガーした場合、またはフィールドにタブで移動した場合、不要なマウスアップイベントがバインドされるというバグがあります-これにより、最初にクリックすると、無視するテキストの選択が解除されます。

解決するには:

var out = $('#out');
var mouseCurrentlyDown = false;

out.focus(function () {
  out.select();

  if (mouseCurrentlyDown) {
    out.one('mouseup', function (e) {
      e.preventDefault();
    });  
  }
}).mousedown(function() {
  mouseCurrentlyDown = true;
});

$('body').mouseup(function() {
  mouseCurrentlyDown = false;
});

注:ユーザーが入力内でマウスダウンし、マウスを入力から移動してからマウスアップすることを考慮したいので、mouseupイベントは入力ではなく本体にある必要があります。

0
Jai