1

jQueryの変更イベントとクリックイベントのタイミングに問題があるようです。私のサイトでは、アラートの代わりにAjax投稿を使用していますが、アラートを使用して再現する方が簡単です。jQueryバージョン1.7.1を使用した単純なHTMLページがあります。

シナリオでは、テキストボックスを編集してから、ボタンを直接クリックします。変更イベントは常に発生しますが、アラートが含まれている場合、クリックイベントが呼び出されることはありません。不正行為をしてアラートの周りにタイムアウトを設定すると(そこにある値を少し試してみる必要があるかもしれません)、クリックイベントは通常どおり呼び出されます。

/ **編集** /変更イベントのどこかにブレークポイントを設定して数秒待つと、クリックイベントも発生しません。

<script type="text/javascript">
$(document).ready(function ()
{
    $("input[type=text]").change(function () {
        //alert('changed');

        $("#text").text('changed');

        setTimeout(function () {
            $("#text").text('changed timeout');
            alert('changed');
        }, 100);

    });

    $("input[type=submit]").click(function () {
        alert('clicked');
        $("#text").text('clicked');
    });
});
  </script>
  <div id="main">
    <div class="container">
        <input type="text" />
        <input type="submit" value="click me" />
        <div id="text" >bla</div>
    </div>
  </div>

保存動作を持つ私のAjax呼び出しは次のとおりです。

$.ajax({
        type: 'POST',
        url: postUrl,
        data: form.serialize(),
        beforeSend: function () {
            // display overlay for work in progress
        },
        success: function (result) {
            updateTableSuccess();
        },
        complete: function () {
            // hide overlay for work in progress
        },
        error: function (jqXHR) {
            if (jqXHR.responseText.length > 0) {
                showErrorMessage(jqXHR.responseText);
            }
        }
    });

オーバーレイは、本体タグに2つのdivを追加するだけです。

/ **編集** /オーバーレイが実際の問題であり、アラートと同じ動作を引き起こし、クリックイベントの発生を停止しているようです。

showWorkInProgress = function (message, elementId)
{
    if ($("#overlay").length == 0)
    {
        $("<div id='overlay' class='ui-widget-overlay'></div>").appendTo("body");
    }

    if ($("#workInProgress").length == 0)
    {
        $("<div id='workInProgress'></div>").appendTo("body");
    }

    $("#workInProgress").html(message);
    if (elementId != null)
    {
        $("#workInProgress").center(elementId);
    }
    else
    {
        $("#workInProgress").center();
    }
    $("#overlay").show();
    $("#workInProgress").show();
};

jQueryがこのように動作する理由と、setTimeoutハックなしでこれをより適切に行う方法を誰かが説明できますか?

助けてくれてありがとう=)

4

3 に答える 3

1

他の誰かが同じ問題を抱えている場合の簡単な答えです。問題は、実際にはページ全体をブロックしているオーバーレイであり、アラートと同じ動作を引き起こします。

私の説明では、 https://stackoverflow.com/users/1861269/john-gerdsenで提案されているように、変更イベントが発生し、UIがブロックされ、クリックイベントが発生しなくなります。

この問題に対して私が見つけた唯一の解決策は、オーバーレイを小さくして、実際にブロックする必要がある部分だけをブロックすることでした。タイムアウトも同様に機能しましたが、マシンごとにパフォーマンスが異なるため、すべての場合に機能するわけではありません。

これは、オーバーレイの問題と戦っている人を助けるかもしれません: クリックがその背後にある要素に落ちることを可能にするHTML「オーバーレイ」

于 2013-01-14T16:20:50.387 に答える
1

Nischo、関数にAJAXコードを挿入するときにブロッキングを複製できませんchange。送信AJAX時にが実行されたときに実行する場合をブロックする場合は、こちらをご覧ください。click

jQuery-イベントが発生した後、onclickイベントリスナーを一時的に無効にするにはどうすればよいですか?

幸運を祈ります。


あなたの説明の後、私はあなたが何を指しているのかわかります。なぜなら、changeイベントはフォーカスを失うことを必要とするので、あなたのclick機能は、あなたのクリックであるフォーカスの喪失によって引き起こされるブロッキングの結果としてオーバーライドされます。

述べたとおりに使用することも、入力のメソッドにtimeOutリファクタリングすることもできます。下記参照:keydowntext

$(document).ready(function () 
{
   $("input[type=submit]").click(function () {
      $("#text").text('clicked');
   });

   $("input[type=text]").keydown(function () {
      alert('changed');
      $("#text").text('changed');
   });
});

フィドル: http: //jsfiddle.net/9WXBe/2/


ニッチョ、

コードを取得してjsFiddleに配置した後、変更イベントが発生しても問題は発生しません。alertコードにが含まれていても。

$("input[type=text]").change()テキストボックスがフォーカスを失うまで起動しません。などの他の要素selectradio、選択または変更が行われた直後にこのアクションを実行します。

これがフィドルです:http: //jsfiddle.net/w9Thc/1/

于 2013-01-07T15:49:15.743 に答える
0

問題はFirefoxでのみ発生するようです。他のブラウザには問題がないようです。テキストフィールドの変更イベントを使用しないように書き直すことで、問題を修正しました。残念ながら、それができない別のコードがあります。どんな種類の「クリック」ボタンでもイベントが見つからないため、変更イベントはUIをブロックしているように見えます。

于 2013-12-12T23:16:01.853 に答える