web-dev-qa-db-ja.com

入力にフォーカスがあるかどうかをテストするためのjQueryの使用

私が構築しているサイトのフロントページでは、いくつかの<div>がCSS :hover疑似クラスを使用してマウスオーバー時に境界線を追加しています。 <div>の1つに<form>が含まれています。これは、jQueryを使用して、その中の入力にフォーカスがある場合に境界を維持します。 IE6が:hovers以外の要素で<a>をサポートしていないことを除けば、これは完全に機能します。したがって、このブラウザでは、$(#element).hover()メソッドを使用してCSS :hoverを模倣するためにjQueryを使用しています。唯一の問題は、jQueryがfocus()hover()の両方の形式を処理するようになったことです。入力にフォーカスがあるときにユーザーがマウスを内外に動かすと、境界線は消えます。

私たちはこのような行動を止めるためにある種の条件を使うことができると考えていました。たとえば、入力にフォーカスがあるかどうかをマウスアウトでテストした場合、境界線が消えるのを防ぐことができます。私の知る限り、jQueryには:focusセレクタがないので、これを実現する方法がわかりません。何か案は?

531
bloudermilk

jQuery 1.6以上

jQueryは :focus セレクタを追加したので、もう自分で追加する必要はありません。 $("..").is(":focus")を使うだけ

jQuery 1.5以下

編集: 時代が変わっても、フォーカスをテストするためのより良い方法を見つけました。新しいお気に入りは Ben Almanのこの要旨です

jQuery.expr[':'].focus = function( elem ) {
  return elem === document.activeElement && ( elem.type || elem.href );
};

Mathias Bynensからの引用 ここ

(elem.type || elem.href)テストはbodyのような誤検知を除外するために追加されたことに注意してください。これにより、フォームコントロールとハイパーリンクを除くすべての要素を確実に除外できます。

新しいセレクタを定義しています。 プラグイン/オーサリング を参照してください。それからあなたはすることができます:

if ($("...").is(":focus")) {
  ...
}

または

$("input:focus").doStuff();

任意のjQuery

どの要素にフォーカスがあるのか​​を知りたいだけなら、

$(document.activeElement)

バージョンが1.6以下になるかどうかわからない場合は、不足している場合は:focusセレクタを追加できます。

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );
884
gnarf

CSS:

.focus {
    border-color:red;
}

JQuery:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });
43
Daniel Moura

これは、現在受け入れられているものよりも強力な答えです。

jQuery.expr[':'].focus = function(elem) {
  return elem === document.activeElement && (elem.type || elem.href);
};

bodyのような誤検知を除外するために(elem.type || elem.href)テストが追加されたことに注意してください。これにより、フォームコントロールとハイパーリンクを除くすべての要素を確実に除外できます。

(/から抜粋した これはGist / /Ben Alman 。)

20
Mathias Bynens

2015年4月の更新

この質問はしばらく前からあり、いくつかの新しい規則が使われ始めているので、私は.liveメソッドが廃止されたことに言及すべきだと私は思います。

代わりに、.onメソッドが導入されました。

彼らの ドキュメンテーション はそれがどのように機能するかを説明するのに非常に役に立ちます。

.on()メソッドは、jQueryオブジェクト内の現在選択されている要素のセットにイベントハンドラを添付します。 jQuery 1.7以降、.on()メソッドはイベントハンドラをアタッチするために必要なすべての機能を提供します。古いjQueryイベントメソッドから変換する方法については、.bind()、.delegate()、および.live()を参照してください。

ですから、あなたが '入力フォーカス'イベントをターゲットにするためには、これをスクリプトの中で使うことができます。何かのようなもの:

$('input').on("focus", function(){
   //do some stuff
});

これは非常に堅牢で、TABキーを使うことさえ可能にします。

13
jbutler483

あなたが何をしているのか完全にはわかりませんが、これはinput要素(またはdiv?)の状態を変数として保存することで達成できるように思えます:

$('div').each(function(){

    var childInputHasFocus = false;

    $(this).hover(function(){
        if (childInputHasFocus) {
            // do something
        } else { }
    }, function() {
        if (childInputHasFocus) {
            // do something
        } else { }
    });

    $('input', this)
        .focus(function(){
            childInputHasFocus = true;
        })
        .blur(function(){
            childInputHasFocus = false;
        });
});
2
James

誰かが気にしているのであれば、今注目を集めるためのもっと良い方法がある、$(foo).focus(...)

http://api.jquery.com/focus/

1
CrackSmoker9000

クラスを使用して要素の状態をマークする代わりに、internal データストア機能 があります。

P.S .:あなたは、data()関数を使って、ブール値と、あなたが望むものは何でも格納することができます。文字列だけではありません:)

$("...").mouseover(function ()
{
    // store state on element
}).mouseout(function ()
{
    // remove stored state on element
});

そしてそれは要素の状態にアクセスすることの問題です。

1
cllpse

これをシミュレートするために mouseOver mouseOut を使うことを考えましたか。 mouseEnter および mouseLeave も調べてください。

1
mkoryak

私がしたことは、jQueryのfocus()関数内で追加および削除される.elementhasfocusという任意のクラスを作成することです。 hover()関数がマウスの外に出ると、.elementhasfocusをチェックします。

if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");

したがって、そのクラスがない場合(read:div内の要素にフォーカスがない場合)、境界線は削除されます。そうでなければ、何も起こりません。

0
bloudermilk

要素がフォーカスされているかどうかを確認するためのプラグインがあります: http://plugins.jquery.com/project/focused

$('input').each(function(){
   if ($(this) == $.focused()) {
      $(this).addClass('focused');
   }
})
0
Murat Çorlu

新しい値を入力する前にユーザーが選択する必要がないように、テキスト入力の内容をselect()(強調表示)するように設定された.live( "focus")イベントがありました。

$(formObj).select();

異なるブラウザ間の混乱のために、選択は時々それを引き起こしたクリックに取って代わられ、テキストフィールド内にカーソルを置くことの直後に内容の選択を解除するでしょう(FFでは大体うまくいきましたがIEでは失敗)

私は選択にわずかな遅延を置くことによってこれを解決することができると思いました...

setTimeout(function(){$(formObj).select();}、200);

これはうまく機能し、選択は持続しますが、面白い問題が発生しました。あるフィールドから次のフィールドに移動すると、選択が行われる前にフォーカスが次のフィールドに切り替わります。 selectはフォーカスを盗むので、フォーカスは戻って新しい "focus"イベントを引き起こします。これは、一連の入力が画面全体で踊ることを選択することになりました。

解決策としては、select()を実行する前にフィールドにフォーカスがあることを確認することが考えられますが、確認する簡単な方法はありません。サブルーチンを含む巨大な関数への単一のjQuery select()呼び出し...

0
Brian

両方の状態(ホバー状態、フォーカス状態)をtrue/falseフラグとして追跡し、どちらかが変更されると、両方がfalseの場合はborderを削除し、それ以外の場合はborderを表示する関数を実行します。

そのため、onfocusはfocused = trueに設定し、onblurはfocus = falseに設定します。 onmouseoverはhovered = trueを設定し、onmouseoutはhovered = falseを設定します。これらの各イベントの後に、ボーダーを追加/削除する関数を実行します。

0
Blixt

私の知る限りでは、画面上の入力にフォーカスがあるかどうかをブラウザに確認することはできません。何らかの種類のフォーカストラッキングを設定する必要があります。

私は通常 "noFocus"という変数を持っていて、それをtrueに設定します。それから、noFocusをfalseにするフォーカスイベントをすべての入力に追加します。次に、noFocusをtrueに設定したすべての入力にぼかしイベントを追加します。

私はこれを非常に簡単に処理するMooToolsクラスを持っています、私はあなたが同じことをするためにjqueryプラグインを作成することができると確信しています。

それが作成されたら、ボーダースワッピングをする前にnoFocusをチェックすることができます。

0
Ryan Florence

フォーカスはありませんが、あります。selected http://docs.jquery.com/Selectors/selected

しかし、選択した内容に基づいて外観を変更したい場合は、おそらくblurイベントを使用してください。

http://docs.jquery.com/Events/blur

0
Chris Brandsma