Issue with DOM manipulation (blockUI or alert()) during a onchange request - prevents other event from firing
EDIT: I wrongly assumed this was caused by blockUI();
I was using Firebug's console.log
to log the message but for the example here I changed to alert so you wouldn't need firebug to replicate. Once I tested it again, I was able to remove blockUI
and the onclick
didn't fire not firing. The issue seems to be whenever the DOM is changing or feedback given it stop the onclick
from firing.
I am having issues with jQuery blockUI plugins and firing two events that are (I think, unless I am losing it) unrelated.
Basically I have textboxes with onchange
events bound to them. The event is responsible for blocking the UI, doing the ajax call and on success unblocking the UI. The ajax is saving the text in memory. The other control is a button with on onclick
event which also block the UI, fire an ajax request saving what's in memory to the database and on success unblock the UI.
Both of these work fine separately. The issue arise when I trigger the onchange
by clicking on the button. Then only the onchange
is fired and the onclick
is ignored.
I can change the text in the checkbox, click on the link and IF jQuery.blockUI()
is present (or an alert) the onchange
alone is fired and the save is never called. If I remove the blockUI
(or an alert) both function are called.
Here's a fully working example where you can see the issue. Please note the setTimeout
are there when I was trying to simulate the ajax delay but the issue is happening without it.
To replicate type something in the textbox and click save. Both event should be firing but only the onchange
is triggered.
<html>
<head>
<script src="http://ajax.googleapis.com/aj开发者_StackOverflowax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://github.com/malsup/blockui/raw/master/jquery.blockUI.js?v2.31"></script>
<script>
function doSomething(){
//$.blockUI();
alert("doing something");
//setTimeout(function(){
//$.unblockUI();
//},500);
}
function save(){
//$.blockUI();
console.log("saving");
//setTimeout(function(){
//$.unblockUI();
//}, 1000);
}
</script>
</head>
<body>
<input id="textbox" type="text" onchange="doSomething();">
<a id="link" href="#"onclick="save()">save</a>
</body>
</html>
There's only going to be one event loop going at any given time in the environment of a single page. If your ajax calls are synchronous, then while one event is being handled then that's all the will be going on. If the browser were to trigger another event loop, well, then it wouldn't be single-threaded. But it is, so it doesn't.
The following "fixed it" using onfocus for the link and the event is triggered. With an onclick it isn't.
This work:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://github.com/malsup/blockui/raw/master/jquery.blockUI.js?v2.31"></script>
<script>
function doSomething(){
alert("blocking UI");
console.log("do something");
//alert("doing something");
//setTimeout(function(){
//$.unblockUI();
//},500);
}
function save(){
//$.blockUI();
console.log("saving");
//setTimeout(function(){
//$.unblockUI();
//}, 1000);
}
function cachebtn()
{
console.log("cache bouton");
}
</script>
</head>
<body>
<input id="textbox1" type="text" onchange="doSomething();">
<input id="textbox2" type="text" onchange="doSomething();">
<a id="link" href="#" onfocus="save()">save</a>
</body>
</html>
This doesn't, the only different is the onclick which isn't firing when the onchange precedes it.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://github.com/malsup/blockui/raw/master/jquery.blockUI.js?v2.31"></script>
<script>
function doSomething(){
alert("blocking UI");
console.log("do something");
//alert("doing something");
//setTimeout(function(){
//$.unblockUI();
//},500);
}
function save(){
//$.blockUI();
console.log("saving");
//setTimeout(function(){
//$.unblockUI();
//}, 1000);
}
function cachebtn()
{
console.log("cache bouton");
}
</script>
</head>
<body>
<input id="textbox1" type="text" onchange="doSomething();">
<input id="textbox2" type="text" onchange="doSomething();">
<a id="link" href="#" onclick="save()">save</a>
</body>
</html>
精彩评论