I seem to have a timing problem with my jQuery change and click events. In my site I have it with an Ajax post instead of an alert, but it's easier to reproduce it using the alert. I have a simple HTML page using jQuery Version 1.7.1.
The scenario is editing the textbox and then directly clicking the button. The change event is always fired but if it contains a alert the click event is never called. If I cheat and put a timeout around the alert (you might have to play around a bit with the values there) the click event is called normally.
/** EDIT **/ If you set a breakpoint somewhere in the change event and wait for a few seconds the click event will aslo fail to fire.
<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>
My Ajax call that has the save behavoir is the following:
$.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);
}
}
});
The overlay is simply appending 2 divs to the body Tag.
/** Edit **/ It seems that the overlay is the real problem and causes the same behavoir as the alert and stops the click event from being fired.
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();
};
Can anyone explain why jQuery behaves like this and how I could do this nicer without the setTimeout hack?
Thanks for any help =)