jQuery更改并单击事件计时

时间:2013-01-07 15:36:46

标签: jquery events timing

我的jQuery更改和点击事件似乎有时间问题。在我的网站中,我使用Ajax帖子而不是警报,但使用警报更容易重现它。我有一个使用jQuery版本1.7.1的简单HTML页面。

方案是编辑文本框,然后直接单击按钮。始终触发change事件,但如果它包含警报,则永远不会调用click事件。如果我作弊并在警报周围放置一个超时(你可能需要在那里玩一下这些值),就会正常调用click事件。

/ **编辑** / 如果在更改事件中的某处设置断点并等待几秒钟,则单击事件将无法触发。

<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 hack的情况下做得更好?

感谢您的帮助=)

3 个答案:

答案 0 :(得分:1)

Nischo,在将AJAX代码插入change函数时,我无法复制阻止。如果您希望阻止AJAX,如果在提交时触发click,则会执行此处。

jQuery - How can I temporarily disable the onclick event listener after the event has been fired?

祝你好运。


在您的解释之后,我确实看到了您所指的内容,因为change事件需要失去焦点才会触发您的click功能被覆盖,因为失去的焦点造成的阻塞是您的点击。

您可以按照自己的说明使用timeOut,也可以在keydown输入上重构text方法。见下文:

$(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/


Nischo,

在获取代码并将其放入jsFiddle后,我没有看到更改事件被触发的任何问题。即使代码中有alert

$("input[type=text]").change()在文本框失去焦点之前不会触发,selectradio等其他元素会在选择或更改后立即执行此操作。

这是小提琴: http://jsfiddle.net/w9Thc/1/

答案 1 :(得分:1)

如果其他人遇到同样的问题,只需要一个简短的答案:问题实际上是覆盖整个页面的叠加层,导致与警报相同的行为。

我的解释是,更改事件被触发,阻止了用户界面,因为https://stackoverflow.com/users/1861269/john-gerdsen的建议,因此无法再触发点击事件。

我发现这个问题的唯一解决方案是使叠加层变小并仅阻挡真正需要阻挡的部分。超时工作也是如此,但并不是因为每台机器都有不同的性能。

这可能有助于任何尝试与叠加问题作斗争的人: HTML "overlay" which allows clicks to fall through to elements behind it

答案 2 :(得分:0)

Firefox似乎只会出现问题。其他浏览器似乎没有问题。我通过重写事情来解决我的问题,不使用文本字段更改事件。不幸的是,我有另一段代码,我不能这样做。更改事件似乎阻止了UI,因为我发现任何类型的“点击”按钮都没有事件。