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


561

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

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


1
それを必要なものと私が何をしているかの数文に要約できますか?
mkoryak 2009年

フォーカスとブラーイベントのキャプチャ(docs.jquery.com/Events/focusdocs.jquery.com/Events/blur)を検討する必要があると思います
Wolfr

関連質問「JavaScript(またはjQuery)に「フォーカス」はありますか?」に回答を投稿しました。[gnarfが引用するクレタスのアプローチ]を強化しました(#2684561)。
luiggitama

回答:


928

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 );

4
これにより、誤検知が発生する可能性があります。詳細については、stackoverflow.com / questions / 967096 /…を参照してください(Ben AlmanおよびDiego Periniに感謝)。
Mathias Bynens、2011年

@Mathias Bynens-更新してくれてありがとう(このコミュニティのwikiの回答を編集して大歓迎です!)
gnarf

1.5と1.6の両方で動作する必要がある場合はどうですか?jQuery自体のフォーカスセレクターをオーバーライドしたくありません。のようなものif (!jQuery.expr[':'].focus) { /* gist from Ben Alman */ }
Betamos

@betamos-まさにその通りです...私はそれを反映するために答えに何かを追加します。
gnarf

2
@Alex-問題を示すjsFiddleでテストケースを減らしてください。私が知る限り、これが「動的」要素で機能しない理由はありません。私は
shenanigans

46

CSS:

.focus {
    border-color:red;
}

jQuery:

  $(document).ready(function() {

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

22

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

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

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

Ben Almanによるこの要点から取得。)


13

2015年4月の更新

この質問はかなり前からあり、いくつかの新しい慣例が出てきたので、この.live方法は減価償却されていることを述べておかなければならないと思います。

その代わりに、この.on方法が導入されました。

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

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

したがって、「入力にフォーカスした」イベントをターゲットにするために、これをスクリプトで使用できます。何かのようなもの:

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

これは非常に堅牢で、Tabキーを使用することもできます。


2

私はあなたが何をしているのか完全にはわかりませんが、これは入力要素(または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;
        });
});

これは私がやったことですが、グローバルJavaScript変数ではなく任意のCSSクラスを使用しました。
牛乳

これのバリエーションを使用しました。新しいjQueryプラグインは必要ありません。それは私を幸せなキャンピングカーにします!
デニスの日

1

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

PS:このdata()関数を使用して、ブール値や必要なものを保存できます。文字列だけではありません:)

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

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



1

これをシミュレートするためにmouseOvermouseOutを使用することを考えましたか?mouseEntermouseLeaveも確認してください


それは本質的に私がjQueryのホバーでやっていることです。マウスイン用とマウスアウト用の2つの関数を提供します。
bloudermilk 2009年

0

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

つまり、onfocusはフォーカス= trueを設定し、onblurはフォーカス= falseを設定します。onmouseoverはhovered = trueを設定し、onmouseoutはhovered = falseを設定します。これらの各イベントの後、境界線を追加/削除する関数を実行します。


0

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

私は通常「noFocus」という変数を持ち、それをtrueに設定します。次に、noFocusをfalseにするすべての入力にfocusイベントを追加します。次に、noFocusをtrueに戻すすべての入力にblurイベントを追加します。

これを非常に簡単に処理するMooToolsクラスがあります。jqueryプラグインを作成して同じことを行えると確信しています。

それが作成されたら、ボーダーの入れ替えを行う前にnoFocusをチェックできます。



0

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

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

1
コアjqueryだけを使用できるのに、なぜプラグインを使用するのですか?
Marcy Sutton、2011

1
あなたが正しいです。しかし、2年前にはこの問題の解決策を知りませんでした。
MuratÇorlu2011

0

テキスト入力の内容をselect()(ハイライト)に設定する.live( "focus")イベントを用意したので、ユーザーは新しい値を入力する前に選択する必要がありません。

$(formObj).select();

異なるブラウザー間の癖のために、選択はそれを引き起こしたクリックによって置き換えられることがあり、テキストフィールド内にカーソルを置くことを優先した直後にコンテンツの選択を解除します(FFではほとんど問題なく動作しましたが、IEでは失敗しました)。

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

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

これは正常に機能し、選択は持続しますが、面白い問題が発生しました。あるフィールドから次のフィールドにタブ移動すると、選択が行われる前にフォーカスが次のフィールドに切り替わります。selectがフォーカスを盗むので、フォーカスは戻って新しい「フォーカス」イベントをトリガーします。これにより、画面全体でダンスを選択する入力のカスケードが発生しました。

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


0

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

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

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


-2

シンプルな

 <input type="text" /> 



 <script>
     $("input").focusin(function() {

    alert("I am in Focus");

     });
 </script>

これは、現在どの要素がフォーカスされているかを通知するものではありません。新しい要素がフォーカスを取得すると呼び出されます。したがって、要素にすでにフォーカスがあり、「これ」がその要素かどうかを知りたい場合、このコードは役に立ちません。
Alexis Wilke、2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.