3

ぼかしに身を隠す2つのinput要素があります。問題は、要素がDOMに非表示になっている後に続く要素をクリックした場合に、ぼかしの原因となったクリックイベントが失われることです。

クリックした要素がぼやけた要素の前にある場合、期待どおりに機能します

この単純なスニペットは、次のことを示しています。

<html>
<script src="./jquery.min.js" ></script>
<script type="text/javascript">
$(document).ready(function() {
        $('input').blur(function(e) {
            console.log('blurred');
            $(this).hide();
        });

        $('.a').click(function() {
            console.log('div clicked');
        });

        $(document).click(function() {
            console.log('doc clicked');
        });
    });
</script>
<body>
<div id="div1">
<div class="a"><input /></div>
<div class="a"><input /></div>
</div>
</body>
</html>

下の入力をクリックすると、上が期待どおりに機能します。「ぼやけた」印刷、「divクリック」、「ドキュメントクリック」の順に表示され、下の入力は非表示になります。

上部の入力をクリックすると、下部の上部の入力が非表示になり、「ぼやけた」印刷のみが表示され、クリックイベントはどこでも処理できなくなります。

の呼び出しhideがコメント化されている場合は、期待どおりに機能します。

使用.liveしても違いはありません。

これを回避する方法を考えることはできますが、どれも非常に優れています。sの順序がinput重要である理由、またはより良い解決策について何か考えはありますか?

ありがとう。

4

3 に答える 3

2

OKOKOKこれは私たちが集合的に一緒に愚かであるだけです。

上から下にクリックしているときに何が起こっているかを見てください。

トップに焦点が当てられています。2番目の入力をクリックすると、クリックイベントが2番目のdivに登録される前にblurイベントが発生します。

何が起こっているのかというと 2番目の入力をクリックしてフォーカスを与えているということです。クリックされたターゲット(2番目の入力)からイベントがバブルアップするため、フォーカスが取得されます。ただし、最初の入力ブラーイベントが最初に発生するため、上部のdivの高さが0に減少し、2番目のdivが現在のマウス位置の範囲を超えてすぐに移動します。したがって、2番目のdivのクリックイベントは発生しません。これは、その前にdivがすでに邪魔にならないように移動されているためです。

このjsfiddleで理由がわかります。http://jsfiddle.net/Z884F/
入力が非表示になった後でもdivの高さを維持するための要素を追加しました。コンソールを見ると、期待どおりに機能していることがわかります。

Firefoxが機能する理由は、Firefoxがイベントのタイミングを少し異なる方法で処理するためです。

以下の私の元の答えを無視してください:

これは非常に奇妙な動作です。MacOS10.7のChromeとSafariで結果を確認しました。ただし、Firefox12.0は期待どおりに機能します。

500msのsetTimeout内でブラーを実行すると、期待どおりに機能します。親divのイベントはまだ削除されていると思いますが。

私はここにjsfiddleを持っています、http: //jsfiddle.net/gsuTw/

これをバグとしてjQuery開発サイトに提出することを強くお勧めします。これはblur()のバグのようです。

于 2012-09-25T05:51:58.910 に答える
0

イベントオブジェクトのsrcElementプロパティは、IEイベントモデルに固有のものです。e.targetjQueryは、存在しない場所を追加することでイベントオブジェクトを「正規化」しますが、次の場所は追加しませんe.srcElement

    // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
    if ( !event.target ) {
        event.target = originalEvent.srcElement || document;
    }

したがって、次のようになります。

>  $(e.srcElement).hide();

'e.srcElement`は未定義を返し、ステートメントは何もしません。

修正は、に変更e.srcElementするか、代わりにe.target使用することです。this

thisリスナーでは、はリスナーを呼び出した要素であるのに対し、targetは元のイベントがディスパッチされた要素であることに注意してください。したがって、同じ要素を参照する場合としない場合があります。

ブラーリスナーでは、、this === event.targetクリックリスナーではありません。

ところで、(このような)エラーを見つけてデバッグするのが難しくなるため、呼び出しを連鎖させることは悪い習慣と見なされます。このようなエラーを黙って無視するライブラリがあると、さらに難しくなります。代わりに、次のことを検討してください。

    $('input').blur(function(e) {

        if (e.srcElement) {
          $(e.srcElement).hide();

        } else {
          // No e.srcElement? what now!!
        }
    });

防御的なコーディング手法はWeb開発者にとっては通用しますが、はるかに信頼性が高く、デバッグが容易です。

于 2012-09-25T05:22:50.720 に答える
0

これは、イベントが飲み込まれた理由の答えにはならないと思います。ただし、入力の位置が問題にならない場合は、代わりに可視性を変更できます。

$('input').blur(function(e) {
    console.log('blurred');
    $(this).css('visibility', 'hidden');
});
于 2012-09-25T06:32:17.737 に答える