1

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

场景是编辑文本框,然后直接单击按钮。change 事件总是被触发,但如果它包含一个警报,则永远不会调用 click 事件。如果我作弊并在警报周围设置超时(您可能需要对那里的值进行一些调整),则通常会调用 click 事件。

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

<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 附加到 body 标签。

/ ** 编辑 ** / 似乎覆盖是真正的问题,并导致与警报相同的行为并停止触发点击事件。

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

感谢您的帮助 =)

4

3 回答 3

1

如果其他人有同样的问题,只是一个简短的回答:问题确实是覆盖整个页面的覆盖,这会导致与警报相同的行为。

我对此的解释是,更改事件被触发,阻止 UI 并且 click 事件不能再被触发,因为https://stackoverflow.com/users/1861269/john-gerdsen所建议的那样。

我为这个问题找到的唯一解决方案是使覆盖层更小,并仅阻止真正需要阻止的部分。超时也有效,但并非在所有情况下都有效,因为每台机器都有不同的性能。

这可能会帮助任何尝试解决覆盖问题的人: HTML“覆盖”,它允许点击落入其后面的元素

于 2013-01-14T16:20:50.387 回答
1

AJAXNischo,将您的代码插入change函数时,我无法复制阻塞。如果您希望在提交AJAX时阻止 if 执行,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()在文本框失去焦点之前不会触发,其他元素(例如select, )radio将在进行选择或更改后立即执行此操作。

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

于 2013-01-07T15:49:15.743 回答
0

问题似乎只发生在 Firefox 上。其他浏览器似乎没有问题。我通过重写不使用文本字段更改事件来解决我的问题。不幸的是,我有另一段代码无法做到这一点。更改事件似乎确实阻止了 UI,因为我在“单击”按钮上没有发现任何类型的触发事件。

于 2013-12-12T23:16:01.853 回答