12

サンプル マークアップを考えると、次のようになります。

<div>
    <input />
    <input />
    <input />
</div>

divjQueryを介して、フォーカスを失ったことをどのように判断できますか?

使用できますfocusout()が、それは私が必要としているものではありません。focusout を使用すると、入力がフォーカスを失っていることを (イベント バブリングを介して) 実際に検出するため、入力から入力への 1 つのタブとしてトリガーされます。

要件を別の言い方をすると、いつフォーカスが div の外に移動したかを知る必要があります。

私は前に同様の質問をしました:

jquery focusin() とバブリングの防止

しかし、これはポップアップ UI に関連しており、その後ろに空白の DIV を挿入し、クリック/フォーカス イベントをトリガーとして配置することで回避できますが、この状況では機能しません。

次に考えたのは、focusout を呼び出すときに focusin をテストすることでした。

    $(".myobject").focusout(function(element) {
    if(!($(this).focusin())){
        console.log('doYourThing ' + $(this));
    }
});

残念ながら、それは機能しません (focusout イベント中に focusin を評価しているため、まだ focusin を検出していないためだと思います。

この問題に対する賢い解決策はありますか? 私が探しているものを正確に実行するネイティブjQueryイベントが欠けているのでしょうか?

アップデート:

実際には、単純化された質問:

相当するものが必要です$('div').blur()が、実際にはdivで機能します(divからぼかしをトリガーできないため)

4

3 に答える 3

19

Pointy の回答を参考にして、もう少し先に進んでください。

(単純な) focuslost イベント プラグインの作成

(function($) {
    // will store the last focus chain
    var currentFocusChain = $();
    // stores a reference to any DOM objects we want to watch focus for
    var focusWatch = [];

    function checkFocus() {
        var newFocusChain = $(":focus").parents().andSelf();
        // elements in the old focus chain that aren't in the new focus chain...
        var lostFocus = currentFocusChain.not(newFocusChain.get());
        lostFocus.each(function() {
            if ($.inArray(this, focusWatch) != -1) {
                $(this).trigger('focuslost');
            }
        });
        currentFocusChain = newFocusChain;
    }
    // bind to the focus/blur event on all elements:
    $("*").live('focus blur', function(e) { 
        // wait until the next free loop to process focus change
        // when 'blur' is fired, focus will be unset
        setTimeout(checkFocus, 0);
    });

    $.fn.focuslost = function(fn) {
        return this.each(function() {
            // tell the live handler we are watching this event
            if ($.inArray(this, focusWatch) == -1) focusWatch.push(this);
            $(this).bind('focuslost', fn);
        });
    };
})(jQuery);

使用例

$("div").focuslost(function() {
  $(this).append("<div>Lost Focus!</div>");
});

jsfiddle デモ

于 2010-06-21T22:49:47.843 に答える
5

注目すべきもう 1 つのプラグインは、Ben Alman のOutside Events プラグインです。特定の要素とその子以外で次のイベントのいずれかがトリガーされるタイミングを検出できますclickoutside, dblclickoutside, focusoutside, bluroutside, mousemoveoutside, mousedownoutside, mouseupoutside, mouseoveroutside, mouseoutoutside, keydownoutside, keypressoutside, keyupoutside, changeoutside, selectoutside, submitoutside

于 2010-06-22T18:16:31.870 に答える
4

さて、うまくいくかもしれないのは、「フォーカス」ハンドラーをすべてにバインドすることであり、<div>他の場所で「フォーカス」イベントを取得したときに、あなたがいないときを知っています。

$('body').live('focus', (function() {
  var inDiv = false;
  return function(e) {
    if ($(this).closest('#theDiv').length)
      inDiv = true;
    else {
      if (inDiv)
        alert("just lost focus!");
      inDiv = false;
    }
  };
 });
于 2010-06-21T22:07:41.000 に答える