5

ぼかしイベントを持つ標準のテキスト入力があります。Blur イベントは、ドキュメント内の何かがクリックされたときに発生する必要があります (入力 AND 以外<div id='show-anyways'></div>)。

<div id='show-anyways'></div>私の問題は、ぼかしイベント機能を無効にするために を追加する方法がわからないことです。

うまくいけば、私は十分に自分自身を説明しました.それはちょっと奇妙な状況だと思います. さらに情報が必要な場合はお知らせください。

4

4 に答える 4

10

イベント ターゲットを使用して、何がクリックされたかを判断します。以下は、要素が DIV または入力の場合、ドキュメントのすべてのクリックを追跡し、blur() をトリガーしません。

var $input=$( '#MY-Input-ID');

$(document).click(function(evt){
   var $tgt=$(evt.target);
   if( !$tgt.is( '#show-anyways') && !$tgt.is($input) ){
         $input.blur()
    }
})

preventPropogation が設定されている要素ではトリガーされません。

于 2012-06-23T22:43:29.117 に答える
1

他のソリューションには欠けているものがいくつかあります。最も重要なことは、ぼかしイベントを呼び出す前に、入力がフォーカスされているかどうかを確認する必要があるということです。もう 1 つは、blur イベントが呼び出されるのは、別の場所をクリックした場合だけではありません。ブラウザーの別のタブに移動したとき、tabまたはshift + tab次/前の入力に移動した場合にも呼び出すことができます。最後に、ターゲット要素がぼかしイベントの例外 (例外の子である可能性がある) であるかどうかを確認するときに、jQuery 関数closest()の使用を検討する必要があります。

そこで、この jQuery プロトタイプ関数を思いつきました。

$.fn.extend({

    blurIfNot : function(options, handler)
    {
        var defaults =
        {
            except : [],
            maxParent : null // A DOM element within which
                             // a matching element may be found
        };
        var opt = $.extend({}, defaults, options);
        var time = new Date().getTime();
        
        this.each(function()
        {
            var thisInp = $(this);
            thisInp[0].blurIfNot = {};
            time += 1000000000000;
            
            var except = opt.except;
            
            if ($.isFunction(opt.except))
            { except = opt.except.call(thisInp[0]); }
            
            function fire_blur_event(_tar, evt, mousedown)
            {
                var proceed = true;
                
                for (var i in except)
                {
                    if (_tar.is(thisInp) ||
                    _tar.closest(except[i], opt.maxParent).length)
                    {
                        proceed = false;
                        break;
                    }
                }
                if (proceed)
                {
                    thisInp[0].blurIfNot.focus = false;
                    handler.call(thisInp[0], evt);
                }
                else if (mousedown)
                {
                    $('html').one('mouseup', function(e)
                    {
                        thisInp[0].focus();
                    });
                }
            }
            
            if (!thisInp[0].blurIfNot.isset)
            {
                $('html').mousedown(function(e)
                {
                    if (thisInp[0].blurIfNot.focus)
                    {
                        var tar = $(e.target);
                        
                        if (!tar.is('input'))
                        { fire_blur_event(tar, e, true); }
                    }
                });
                
                $(window).blur(function(e)
                {
                    if (thisInp[0].blurIfNot.focus)
                    {
                        thisInp[0].blurIfNot.focus = false;
                        handler.call(thisInp[0], e);
                    }
                });
            }
            else
            {   // to be able to update the input event if you have
                // created new inputs dynamically
                $('input').off('focus.blufIfNot' + time);
            }
            
            $('input').on('focus.blurIfNot' + time, function(e)
            {
                var tar = $(e.target);
                
                if (tar[0] == thisInp[0])
                { thisInp[0].blurIfNot.focus = true; }
                
                else if (thisInp[0].blurIfNot.focus)
                { fire_blur_event(tar, e); }
            });
            
            thisInp[0].blurIfNot.isset = true;
        });
        return this;
    }
});

$('#input_blur_if_not').blurIfNot(
{
    except : [
        $('.autocomplete'), $('.question')
    ],
    // You can also define the elements with a function:
    // except : function()
    // {
    //     return [ $(this).parent().find('.autocomplete') ];
    // },
    maxParent : $('#parent')[0] // optional
},
function(e)
{
    var rand = Math.random();
    
    $('#test').css('padding', rand * 100 + "px").
    html(rand + " blur !");
});
.autocomplete {
    background: #eee;
}
.autocomplete, input {
    width: 200px;
    padding: 3px;
    border: 1px solid #555;
}
.question {
    display:inline-block;
    border-radius:50%;
    background:#137dba;
    color:#fff;
    font-weight:bold;
    padding:2px 7px;
    cursor:pointer;
}
#test {
    position:absolute;
    top:0;
    left:260px;
    color:red;
    font-weight:bold;
    padding:10px 0;
    vertical-align:bottom;
}
<script src="http://code.jquery.com/jquery-latest.js"></script>

<div id="parent">
    
    <input value="an input" />
    <br><br>
    <input id="input_blur_if_not" value="input with autocomplete menu" />
    
    <div class="question">?</div>
    <div class="autocomplete">
        <div>option 1</div>
        <div>option 2</div>
    </div>
    <br>
    <input value="another input" />
    <div id="test"></div>
  
</div>

Chrome と IE11 でテスト済み。さらに説明が必要な場合は、お気軽にコメントしてください。

于 2015-09-15T22:11:53.467 に答える
1

更新:私のソリューションを完全に書き直す必要がありました。blurイベント ハンドラーは、フォーカスを失うイベントに関連付けられます。イベントに似ていれば、どのmouseout要素がフォーカスを取得するかを知ることができますが、そのような運はありません。.clickそのため、イベントをリッスンする代わりに、キャプチャ イベントに頼る必要があり、それに基づいて関数をトリガーする必要がありblurます。

var inputIsBlurred = function() { 
   console.log('Run away!!!');
};
$(document).click(function(e){
  var $target = $(e.target);
  console.log($target);
  if ($target.is('#some_input') // fired by an input - no special effects
      || $target.is('#show-anyways') // fired by 'show-anyways' div
      || $target.parents('#show-anyways').length > 0 // ... or its children
  ) {
      return true; // move along, nothing to do here
  }
  inputIsBlurred();
});​

ここで遊ぶためのフィドルです。私の元の答えによって引き起こされた混乱をお詫びします。(

于 2012-06-23T22:40:17.893 に答える
0

次のようなロジックを追加してみてください。

$('input').blur(function(e){
var tester = e.target;
if ($(tester).attr('id') == 'show-anyways'){
return false;
}
else {
// do something?
}

});

これは基本的にぼかしが発生したときに起動し、クリック/ターゲットされたものをチェックし、それがたまたまショーである場合は false を返し、何もしなくなります。とにかくそれが表示されない場合、それはあなたのぼかしイベントを行うことができますか?

未確認ですが、これはどういう意味ですか?

于 2012-06-23T22:40:01.293 に答える